C#以编程方式从代码活动WF 4.0内部终止工作流

时间:2013-10-09 06:24:52

标签: c# .net .net-4.0 workflow-foundation-4 workflow-foundation

我在 Windows Workflow Foundation Service 中托管了代码活动,我想根据我从数据库中检查的某些值来终止工作流程。我不想使用 Throw Exception 方法,我需要在“Code Activity”代码中进行,而不是从设计器 STRONG>。我仍然是 WWF 的初学者,我尝试了以下方法,即创建工作流应用程序,并在代码活动的当前实例上初始化它,但它不起作用。我需要首先捕获当前活动实例的父工作流应用程序,然后调用终止方法。

   WorkflowApplication wfApp = new WorkflowApplication(this);
   wfApp.Terminate("The following workflow is terminating");

感谢您对此的帮助

4 个答案:

答案 0 :(得分:5)

要优雅地终止,只需使用TerminateWorkflow作为子活动。这将调用WorkflowApplication.Completed操作。

public class CanceledActivity : NativeActivity
{
    private readonly TerminateWorkflow terminateWorkflow = new TerminateWorkflow
        {
            Reason = "Reason why I'm terminating!"
        };

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddImplementationChild(terminateWorkflow);
    }

    protected override void Execute(NativeActivityContext context)
    {
        context.ScheduleActivity(terminateWorkflow);
    }
}

或者您可以抛出异常,但这会调用WorkflowApplication.OnUnhandledException

public class CanceledActivity : NativeActivity
{
    protected override void Execute(NativeActivityContext context)
    {
        throw new Exception("this will not gracefully terminate the workflow")
    }
}

还有很多其他的方法,也取决于你想做什么以及什么时候你想做。请记住,由于其异步性,工作流只会在可能的情况下终止。

答案 1 :(得分:1)

您可以将WorkflowApplication放入应用程序上下文扩展中,然后通过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);

答案 2 :(得分:0)

在我看来,实际上您在目前想要使用的一项活动中有两项活动。 流程图(即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;
}

从方法体内返回的是代码气味,指出需要重新思考工作流程。健康的方法只有一个回报。 即。

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

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

    return price;
}

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

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

请注意,可以创建由其他活动组成的创建活动,以便您可以将上图中的活动嵌入到单个活动中并隐藏详细信息。它与代码示例中的CalculatePrice方法相同。调用者实际上不必知道如何计算价格。

答案 3 :(得分:0)

您可以这样做:

throw new System.Activities.Statements.WorkflowTerminatedException("reason string");

在代码中的任何位置进行操作:)