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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM