在上一節Workflow筆記1——工作流介紹中,介紹的是流程圖工作流,後來微軟又推出了狀態機工作流,它比流程圖功能更加強大。
新建項目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
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,處理所需的工作流生命周期事件,並通過調用 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,一個線程通過調用等待一個信號 WaitOne 上 AutoResetEvent。
在工作流實例化之前,就創建一個AutoResetEvent對象。
AutoResetEvent syncEvent = new AutoResetEvent(false);
然後在工作流的Completed事件中,執行Set方法,將事件狀態設置為有信號,從而允許一個或多個等待線程繼續執行,說白了就是一個喚醒操作。
syncEvent.Set();
最後在Run方法的後面,添加
syncEvent.WaitOne();
WaitOne方法將阻止當前線程,直到當前 WaitHandle 收到信號,從而實現等待工作流線程運行完成的功能。
源碼下載:WorkflowConsoleApp2.zip