简体   繁体   English

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

[英]C# Terminate a Workflow Programatically from inside Code Activity WF 4.0

I have a code Activity hosted inside a Windows Workflow Foundation Service , I want to terminate the workflow based on some values I am checking from the database. 我在Windows Workflow Foundation Service中托管了一个代码Activity ,我希望根据我从数据库中检查的一些值来终止工作流。 I don't want to use the Throw Exception method, and I need to do it from inside the "Code Activity" Code, not from the designer . 我不想使用Throw Exception方法,我需要从“Code Activity”代码中进行,而不是从设计器中进行 I am still a beginner in WWF , I tried the below method, which is creating a workflow application, and initializing it on the current instance of the code activity, but it didn't work. 我仍然是WWF的初学者,我尝试了以下方法,即创建工作流应用程序,并在代码活动的当前实例上初始化它,但它不起作用。 I need to capture the parent workflow application of the current activity instance first, then call the Terminate method. 我需要首先捕获当前活动实例的父工作流应用程序 ,然后调用Terminate方法。

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

Thanks for your help on this 感谢您的帮助

To terminate gracefully, just use TerminateWorkflow as a child activity. 要正常终止,只需使用TerminateWorkflow作为子活动。 This will invoke WorkflowApplication.Completed action. 这将调用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);
    }
}

Or you can just throw an exception but this will invoke WorkflowApplication.OnUnhandledException instead. 或者您可以抛出异常,但这将调用WorkflowApplication.OnUnhandledException

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

There're a bunch of other ways of doing it, also depending on what you want to do and when you want to do it. 还有很多其他的方法,也取决于你想做什么以及什么时候你想做。 Keep in mind that workflow will only terminate when it can, due to its asynchronous nature. 请记住,由于其异步性,工作流只会在可能的情况下终止。

You can put the WorkflowApplication into the application context extensions which will then be available through the ActivityContext class. 您可以将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);

It looks to me that in fact you have two activities in the one activity you currently want to use. 在我看来,实际上你在目前想要使用的一个活动中有两个活动。 What you are asking for is not possible in flowcharts (ie Visio) either because one activity has only one exit what can be linked to a next activity (ie an end state), you'd need a decision block to be able to take a different route. 流程图(即Visio)中不可能要求的是因为一个活动只有一个可以链接到下一个活动的退出(即结束状态),您需要一个决策块才能获取不同的路线。

This is an example for what you try to translate into a flowchart: 这是您尝试转换为流程图的示例:

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;
}

Return from within body of a method is a code smell pointing to the need of rethinking the workflow. 从方法体内返回的是代码气味,指出需要重新思考工作流程。 A healthy method has only one return. 健康的方法只有一个回报。 Ie

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

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

    return price;
}

Now this second method is straightforward to translate into a flowchart/workflow. 现在,第二种方法可以直接转换为流程图/工作流程。 在此输入图像描述

If you have a different case please provide a sample flowchart or other diagram. 如果您有不同的情况,请提供示例流程图或其他图表。 The rule of thumb is that if you can't draw a flowchart, a state machine or sequence diagram then it can't be implemented with Microsoft Workflow. 经验法则是,如果您无法绘制流程图,状态机或序列图,则无法使用Microsoft Workflow实现它。

Note that it is possible to create create activities what are composed of other activities so you could embed the activities on diagram above into a single activity and hide the details. 请注意,可以创建由其他活动组成的创建活动,以便您可以将上图中的活动嵌入到单个活动中并隐藏详细信息。 It would be the same like CalculatePrice method in code samples. 它与代码示例中的CalculatePrice方法相同。 The caller doesn't actually have to know how the price is calculated. 调用者实际上不必知道如何计算价格。

You can just do: 你可以这样做:

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

from any where in your code and be done with it :) 从您的代码中的任何位置,并完成它:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM