zoukankan      html  css  js  c++  java
  • Workflow笔记2——状态机工作流

    状态机工作流

        在上一节Workflow笔记1——工作流介绍中,介绍的是流程图工作流,后来微软又推出了状态机工作流,它比流程图功能更加强大。

        状态机工作流:就是将工作流系统中的所有的工作节点都可以看做成一个状态节点。每个节点都有N个状态,其中都包含初始状态、进入状态、离开状态等。当节点的状态变化的时候会执行某个节点。

        新建项目StatueWorkflowConsoleApp

        自动添加了一个起始节点和一个状态节点.

     

        运行结果如下:

        注意执行顺序。接下来,扩展此工作流。

        1、设置全局变量Num

        2、双击T1,为变量Num赋值

     

    new Random().Next(0,10)

        运行结果如下:

    启动工作流

        之前我们新建的工作流项目,都是通过如下方式来启动工作流的。

                Activity workflow1 = new Workflow1();
                WorkflowInvoker.Invoke(workflow1);

        而在工作中,我们通常不能通过这样的方式来启动工作流。因为我们的流程启动后,我需要监控流程的各种状态。而我们通过Invoke的方式启动工作流,是无法监控工作流的状态的。我们可以通过WorkflowApplication类启动工作流。参考:https://msdn.microsoft.com/zh-cn/library/system.activities.workflowapplication(v=vs.110).aspx

        WorkflowInvoker 包含同步调用工作流的实例方法和静态方法。WorkflowInvoker 不允许实例控件,如保持、卸载或恢复书签。

        WorkflowApplication 类为单个工作流实例提供宿主。 它是由工作流运行时管理的实际工作流实例的代理。

    • 创建新的工作流实例,或从实例存储区中加载工作流实例。
    • 提供扩展以供工作流实例内的活动使用。
    • 控制工作流实例的执行。
    • 恢复由工作流实例内的活动创建的书签。
    • 保留或卸载工作流实例。
    • 接收工作流实例生命周期事件通知。

        1、新建Windows窗体应用程序,WindowsWorkFlowApp

        2、右键单击项目WindowsWorkFlowApp,新建活动,添加状态机

        3、双击State1,添加输入参数

        4、再添加一个状态和结束状态

        5、双击FinalState,在其中添加输出

        修改State2

        6、修改“启动工作流”按钮的事件代码如下:

            private void btnStartWorkFlow_Click(object sender, EventArgs e)
            {
                WorkflowApplication app = new WorkflowApplication(new Activity1(), new Dictionary<string, object>() { 
                {"InputName","神刀张三"}
                });
                app.Run();
            }

        我们来看下WorkflowApplication的构造函数。

    构造函数

    名称

    说明

    WorkflowApplication(Activity)

    使用指定的工作流定义创建 WorkflowApplication 类的新实例。

    WorkflowApplication(Activity, IDictionary<String, Object>)

    创建 WorkflowApplication 类的新实例,该实例使用指定的工作流定义和参数值。

    WorkflowApplication(Activity, IDictionary<String, Object>, WorkflowIdentity)

    创建的新实例 WorkflowApplication 类,该类使用指定的工作流定义和参数值和定义标识。

    WorkflowApplication(Activity, WorkflowIdentity)

    创建的新实例 WorkflowApplication 使用指定的工作流定义和定义标识的类。

        7、由于我创建的是Windows应用程序,那么要想输出控制台信息,我们必须修改项目的输出方式

        8、运行项目

    WorkflowApplication生命周期

        那么我们如何来监控工作流的状态呢,我们可以使用指定的工作流定义构造 WorkflowApplication,处理所需的工作流生命周期事件,并通过调用 Run 来调用工作流。

    在Run方法调用之前,我们来注册生命周期事件,添加代码如下:

     #region 工作流生命周期事件
                app.Unloaded = delegate(WorkflowApplicationEventArgs er)
                  {
                      Console.WriteLine("工作流 {0} 卸载.", er.InstanceId);
                  };
                app.Completed = delegate(WorkflowApplicationCompletedEventArgs er)
                {
                    Console.WriteLine("工作流 {0} 完成.", er.InstanceId);
                };
                app.Aborted = delegate(WorkflowApplicationAbortedEventArgs er)
                {
                    Console.WriteLine("工作流 {0} 终止.", er.InstanceId);
                };
                app.Idle = delegate(WorkflowApplicationIdleEventArgs er)
                {
                    Console.WriteLine("工作流 {0} 空闲.", er.InstanceId);
                };
                app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs er)
                {
                    Console.WriteLine("持久化");
                    return PersistableIdleAction.Unload;
                };
                app.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs er)
                {
                    Console.WriteLine("OnUnhandledException in Workflow {0}
    {1}",
           er.InstanceId, er.UnhandledException.Message);
                    return UnhandledExceptionAction.Terminate;
                }; 
                #endregion

        再次运行项目,结果如下:

    多线程信号量机制

        Run方法会开启一个新的线程。而通常,我们需要等待工作流运行完成之后再回到主线程。那么我们可以使用AutoResetEvent一个线程通过调用等待一个信号 WaitOneAutoResetEvent

    在工作流实例化之前,就创建一个AutoResetEvent对象。

    AutoResetEvent syncEvent = new AutoResetEvent(false);

        然后在工作流的Completed事件中,执行Set方法,将事件状态设置为有信号,从而允许一个或多个等待线程继续执行,说白了就是一个唤醒操作。

    syncEvent.Set();

        最后在Run方法的后面,添加

    syncEvent.WaitOne();

        WaitOne方法将阻止当前线程,直到当前 WaitHandle 收到信号,从而实现等待工作流线程运行完成的功能。

        源码下载:WorkflowConsoleApp2.zip

  • 相关阅读:
    Codeforces Round #568 (Div. 2) D. Extra Element
    Codeforces Round #567 (Div. 2) B. Split a Number
    [dp+博弈]棋盘的必胜策略
    [暴力+前缀和]2019牛客暑期多校训练营(第六场)Upgrading Technology
    [set]Codeforces 830B-Cards Sorting
    [二分]煤气灶
    [STL] Codeforces 69E Subsegments
    剑指offer——判断B树是否是A树的子结构
    在浏览器地址栏输入URL执行后网页显示全过程
    链表反转【图解】
  • 原文地址:https://www.cnblogs.com/jiekzou/p/6192813.html
Copyright © 2011-2022 走看看