3

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

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

感谢您对此的帮助

4

4 回答 4

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")
    }
}

还有很多其他方法可以做到这一点,也取决于你想做什么以及什么时候做。请记住,由于其异步性质,工作流只会在可以终止时终止。

于 2013-10-09T13:02:26.930 回答
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);
于 2013-10-09T06:41:00.417 回答
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;
}

从方法体内部返回是一种代码异味,表明需要重新考虑工作流程。一个健康的方法只有一个回报。IE

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

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

    return price;
}

现在,第二种方法可以直接转换为流程图/工作流程。 在此处输入图像描述

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

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

于 2014-06-23T09:02:30.527 回答
0

你可以这样做:

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

从您的代码中的任何位置并完成它:)

于 2018-10-03T18:28:50.600 回答