C#从内部代码活动WF 4.0以编程方式终止工作流 我在 Windows工作流基础服务中有一个代码活动,我想基于从数据库中检查的一些值来终止工作流。我不想使用抛出异常方法,我需要从的“代码活动”代码内部执行,而不是从设计器执行。我仍然是WWF的初学者,我尝试了下面的方法,即创建一个工作流应用程序,并在代码活动的当前实例上初始化它,但它不起作用。我需要首先捕获当前活动实例的父工作流应用程序,然后调用终止方法 WorkflowApplication wfApp = new WorkflowApplication(this); wfApp.Terminate("The following workflow is terminating");

C#从内部代码活动WF 4.0以编程方式终止工作流 我在 Windows工作流基础服务中有一个代码活动,我想基于从数据库中检查的一些值来终止工作流。我不想使用抛出异常方法,我需要从的“代码活动”代码内部执行,而不是从设计器执行。我仍然是WWF的初学者,我尝试了下面的方法,即创建一个工作流应用程序,并在代码活动的当前实例上初始化它,但它不起作用。我需要首先捕获当前活动实例的父工作流应用程序,然后调用终止方法 WorkflowApplication wfApp = new WorkflowApplication(this); wfApp.Terminate("The following workflow is terminating");,c#,.net,.net-4.0,workflow-foundation-4,workflow-foundation,C#,.net,.net 4.0,Workflow Foundation 4,Workflow Foundation,感谢您在这方面的帮助您可以将Workflow应用程序放入应用程序上下文扩展中,该扩展将通过ActivityContext类提供 // Add the application to it's own context _workflowApplication.Extensions.Add(_workflowApplication); // Access the application in your activity var application = context.GetExtension&l

感谢您在这方面的帮助

您可以将Workflow应用程序放入应用程序上下文扩展中,该扩展将通过ActivityContext类提供

// Add the application to it's own context
_workflowApplication.Extensions.Add(_workflowApplication);

// Access the application in your activity
var application = context.GetExtension<WorkflowApplication>();
application.BeginTerminate(new WorkflowException(error), null, null);
//将应用程序添加到自己的上下文中
_workflowApplication.Extensions.Add(\u workflowApplication);
//访问活动中的应用程序
var application=context.GetExtension();
application.begminnate(新的WorkflowException(错误),null,null);

要优雅地终止,只需将其用作子活动即可。这将调用操作

或者您可以只抛出一个异常,但它将调用


还有很多其他的方法,也取决于你想做什么和什么时候做。请记住,由于工作流的异步性质,它只有在能够终止时才会终止

在我看来,事实上,您当前想要使用的一个活动中有两个活动。 您所要求的在流程图(即Visio)中是不可能的,因为一个活动只有一个出口可以链接到下一个活动(即结束状态),您需要一个决策块才能采取不同的路线

以下是您试图转换为流程图的示例:

public int CalculatePrice(string parameters)
{
    // Calculate result.
    var price = 5;

    // Are we done?
    if (!IsVATNeeded(price))
    {
        return price;
    }

    // Do more calculations.
    price = price * vat;

    return price;
}
从方法体内部返回是一种代码气味,表明需要重新考虑工作流。健康的方法只有一个返回。 即

现在,第二种方法可以直接转换为流程图/工作流。

如果您有不同的案例,请提供流程图或其他图表示例。 经验法则是,如果无法绘制流程图、状态机或序列图,则无法使用Microsoft Workflow实现

注意,可以创建由其他活动组成的活动,这样您就可以将上图中的活动嵌入到单个活动中并隐藏详细信息。这与代码示例中的CalculatePrice方法相同。打电话的人实际上不必知道价格是如何计算的。

您只需执行以下操作即可:

抛出新系统.Activities.Statements.WorkflowTerminatedException(“原因字符串”)


从代码中的任何地方开始,然后使用它:)

谢谢您的回复,也许我的回答很愚蠢,我尝试了,它给了我对象引用,而不是设置为对象的实例。我是否应该从活动外部将WorkflowApplication变量作为参数传递?@HassanMokdad您需要将应用程序添加到其扩展中—这有点反常,但却是我发现的最简单的方法。答案已经更新。这并不是最正确的方法。您正在将约束附加到工作流,以使其始终具有WorkflowApplication扩展。使用@Jota我喜欢你的解决方案-编写活动感觉很好。我必须阅读有关子活动的内容,并在我的项目中试用。这种方法很有效,但我找不到从调用terminate的活动中获取OutArguments的方法。它还将ActivityInstanceState设置为Faulted,而理想的解决方案是返回Closed(也称为completed)。希望WF4在Visio中有一个正确的f****%的结束节点。@ RJB我完全理解你所说的,并且从业务经理的角度来看,绘制商业规则是完全有意义的,但是,如果你处于这样的情况下,90%的时间你应该退后一步,重新考虑,因为在中途终止中间的东西在编码世界中是不自然的。WF4应该被视为一种编程语言,通过它,您可以使用活动绘制算法。在实际语言中,如果您在中间终止一个方法,这是因为您只是在做一些事情(而不是计算一些事情),并且您将返回void,而不需要输出参数。也就是说,如果您需要从刚刚执行的(一半)工作流返回信息,只需将该信息写到某个地方,就像在void方法中一样。查看WF4 lib代码的特定位置,TerminateWorkflow是一个众所周知的活动,当使用它时,您基本上是在说“我知道我正在破坏一些东西,扰乱状态和执行,但请尽快终止工作流”。这就是为什么它以错误状态结束,也就是为什么当您在执行过程中破坏了工作流状态时,很难返回输出参数。
public class CanceledActivity : NativeActivity
{
    protected override void Execute(NativeActivityContext context)
    {
        throw new Exception("this will not gracefully terminate the workflow")
    }
}
public int CalculatePrice(string parameters)
{
    // Calculate result.
    var price = 5;

    // Are we done?
    if (!IsVATNeeded(price))
    {
        return price;
    }

    // Do more calculations.
    price = price * vat;

    return price;
}
public int CalculatePrice(string parameters)
{
    var price = CalculatePriceWithoutVAT(parameters);

    if (IsVATNeeded(parameters))
    {
        price = ApplyVAT(price);
    }

    return price;
}