在上一節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