热线(9:00-18:00):13544706711
当前位置: 首页 > 教程技巧 > 

Workflow笔记2——状态机工作流

时间: 2016/12/23 08:34:34

状态机工作流


    在上一节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)



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



WorkflowApplication(Activity, IDictionary, 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}\n{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