共用方式為


HOW TO:執行工作流程

本主題僅適用於 Windows Workflow Foundation 4。

本主題將延續 Windows Workflow Foundation 使用者入門教學課程,並討論如何執行前一個 HOW TO:建立工作流程主題中所定義的工作流程。

Dd489463.note(zh-tw,VS.100).gif注意:
「使用者入門」教學課程中的每個主題都與之前的主題息息相關。 若要完成此主題,您必須先完成 HOW TO:建立活動HOW TO:建立工作流程

若要開啟工作流程主機專案

  1. 使用 Visual Studio 2010,從上一個 HOW TO:建立工作流程主題中開啟方案。

  2. 按兩下 [方案總管] 中的 [Program.cs] 或 [Module1.vb],顯示其程式碼。

    Dd489463.Tip(zh-tw,VS.100).gif提示:
    如果沒有顯示 [方案總管] 視窗,請選取 [檢視] 功能表上的 [方案總管]。

    因為這個專案是使用 [工作流程主控台應用程式] 範本所建立,所以 [Program.cs] 或 [Module1.vb] 會包含以下的基本工作流程裝載程式碼。

    WorkflowInvoker.Invoke(New Workflow1())
    
    WorkflowInvoker.Invoke(new Workflow1());
    

    這個產生的裝載程式碼會使用 WorkflowInvokerWorkflowInvoker 提供如同方法呼叫般叫用工作流程的簡易方法,且僅適用於不使用持續性的工作流程。WorkflowApplication 提供更豐富的執行工作流程模式,包含開發週期事件的通知、執行控制、繼續書籤與持續性。 此範例會使用書籤且將 WorkflowApplication 用於裝載工作流程。 將下列 usingImports 陳述式加入至 Program.csModule1.vb 上層的現有 usingImports 陳述式下方。

    Imports System.Threading
    
    using System.Threading;
    

    使用以下基本 WorkflowApplication 裝載程式碼,取代使用 WorkflowInvoker 的程式碼行。 這個範例裝載程式碼會示範裝載及叫用工作流程的基本步驟,但是尚未包含從這個主題成功執行工作流程的功能。 在下列步驟中,會修改此基本程式碼,並加入其他功能,直到應用程式完成為止。

    Dim syncEvent As New AutoResetEvent(False)
    
    Dim wfApp As New WorkflowApplication(New Workflow1())
    
    wfApp.Completed = _
        Sub(e As WorkflowApplicationCompletedEventArgs)
            syncEvent.Set()
        End Sub
    
    wfApp.Aborted = _
        Sub(e As WorkflowApplicationAbortedEventArgs)
            Console.WriteLine(e.Reason)
            syncEvent.Set()
        End Sub
    
    wfApp.OnUnhandledException = _
        Function(e As WorkflowApplicationUnhandledExceptionEventArgs)
            Console.WriteLine(e.UnhandledException)
            Return UnhandledExceptionAction.Terminate
        End Function
    
    wfApp.Run()
    
    syncEvent.WaitOne()
    
    AutoResetEvent syncEvent = new AutoResetEvent(false);
    
    WorkflowApplication wfApp =
        new WorkflowApplication(new Workflow1());
    
    wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
    {
        syncEvent.Set();
    };
    
    wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
    {
        Console.WriteLine(e.Reason);
        syncEvent.Set();
    };
    
    wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
    {
        Console.WriteLine(e.UnhandledException.ToString());
        return UnhandledExceptionAction.Terminate;
    };
    
    wfApp.Run();
    
    syncEvent.WaitOne();
    

    此程式碼會建立 WorkflowApplication、訂閱三個工作流程開發週期事件、使用 Run 的呼叫來啟動工作流程,然後等候工作流程完成。 當工作流程完成時,會設定 AutoResetEvent 且主機應用程式會完成。

若要設定工作流程的輸入引數

  1. 將下列陳述式加入至 Program.csModule1.vb 上層的現有 usingImports 陳述式下方。

    Imports System.Collections.Generic
    
    using System.Collections.Generic;
    
  2. 使用下列建立與傳遞參數字典到所建立之工作流程的程式碼,取代建立新 WorkflowApplication 的程式碼行。

    Dim inputs As New Dictionary(Of String, Object)
    inputs.Add("MaxNumber", 100)
    
    Dim wfApp As New WorkflowApplication(New Workflow1(), inputs)
    
    var inputs = new Dictionary<string, object>() { { "MaxNumber", 100 } };
    
    WorkflowApplication wfApp =
        new WorkflowApplication(new Workflow1(), inputs);
    

    此字典包含具有 MaxNumber 索引鍵的一個項目。 輸入字典中的索引鍵對應於工作流程根活動的輸入引數。工作流程會使用 MaxNumber 來判斷隨機產生之號碼的上限。

若要擷取工作流程的輸出引數

  1. 修改 Completed 處理常式來擷取與顯示工作流程使用的轉換次數。

    wfApp.Completed = _
        Sub(e As WorkflowApplicationCompletedEventArgs)
            Dim Turns As Integer = Convert.ToInt32(e.Outputs("Turns"))
            Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns)
    
            syncEvent.Set()
        End Sub
    
    wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
    {
        int Turns = Convert.ToInt32(e.Outputs["Turns"]);
        Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns);
    
        syncEvent.Set();
    };
    

若要繼續書籤

  1. 將下列程式碼加入至目前 AutoResetEvent 宣告正後方的 Main 方法上方。

    Dim idleEvent As New AutoResetEvent(False)
    
    AutoResetEvent idleEvent = new AutoResetEvent(false);
    
  2. 將以下的 Idle 處理常式加入至 Main 中現有三個工作流程開發週期處理常式的正下方。

    wfApp.Idle = _
        Sub(e As WorkflowApplicationIdleEventArgs)
            idleEvent.Set()
        End Sub
    
    wfApp.Idle = delegate(WorkflowApplicationIdleEventArgs e)
    {
        idleEvent.Set();
    };
    

    每當工作流程變成閒置狀態,等候下一項猜測值時,就會呼叫此處理常式並設定 idleAction AutoResetEvent。 下列步驟中的程式碼會使用 idleEventsyncEvent 來判斷工作流程是否要等候下一項猜測值或已完成。

    Dd489463.note(zh-tw,VS.100).gif注意:
    在此範例中,主機應用程式會使用 CompletedIdle 處理常式中的自動重設事件,以同步化主機應用程式與工作流程的進度。 繼續書籤前,封鎖與等候工作流程變成閒置狀態並非必要的操作,但是在此範例中,必須同步化事件,如此主機才會知道工作流程是否已完成,或是否正在等候更多使用 Bookmark 的使用者輸入。 如需詳細資訊,請參閱書籤.

  3. 移除對 WaitOne 的呼叫,並以程式碼取代它來收集來自使用者的輸入,並繼續 Bookmark

    移除下列程式碼行。

    syncEvent.WaitOne()
    
    syncEvent.WaitOne();
    

    以下列範例取代它。

    ' Loop until the workflow completes.
    Dim waitHandles As WaitHandle() = New WaitHandle() {syncEvent, idleEvent}
    Do While WaitHandle.WaitAny(waitHandles) <> 0
        'Gather the user input and resume the bookmark.
        Dim validEntry As Boolean = False
        Do While validEntry = False
            Dim Guess As Integer
            If Int32.TryParse(Console.ReadLine(), Guess) = False Then
                Console.WriteLine("Please enter an integer.")
            Else
                validEntry = True
                wfApp.ResumeBookmark("EnterGuess", Guess)
            End If
        Loop
    Loop
    
    // Loop until the workflow completes.
    WaitHandle[] handles = new WaitHandle[] { syncEvent, idleEvent };
    while (WaitHandle.WaitAny(handles) != 0)
    {
        // Gather the user input and resume the bookmark.
        bool validEntry = false;
        while (!validEntry)
        {
            int Guess;
            if (!Int32.TryParse(Console.ReadLine(), out Guess))
            {
                Console.WriteLine("Please enter an integer.");
            }
            else
            {
                validEntry = true;
                wfApp.ResumeBookmark("EnterGuess", Guess);
            }
        }
    }
    

若要建置及執行應用程式

  1. 以滑鼠右鍵按一下 [方案總管] 中的 [WorkflowConsoleApplication1],並選取 [設定為啟始專案]。

  2. 按 CTRL+F5 建置並執行應用程式。 試著盡量在幾次轉換間猜測數字。

    如需如何將持續性加入至工作流程應用程式的指引,請參閱下一個主題 HOW TO:建立與執行長期執行的工作流程

範例

以下範例是 Main 方法的完整程式碼清單。

Sub Main()
    Dim syncEvent As New AutoResetEvent(False)
    Dim idleEvent As New AutoResetEvent(False)

    Dim inputs As New Dictionary(Of String, Object)
    inputs.Add("MaxNumber", 100)

    Dim wfApp As New WorkflowApplication(New Workflow1(), inputs)

    wfApp.Completed = _
        Sub(e As WorkflowApplicationCompletedEventArgs)
            Dim Turns As Integer = Convert.ToInt32(e.Outputs("Turns"))
            Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns)

            syncEvent.Set()
        End Sub

    wfApp.Aborted = _
        Sub(e As WorkflowApplicationAbortedEventArgs)
            Console.WriteLine(e.Reason)
            syncEvent.Set()
        End Sub

    wfApp.OnUnhandledException = _
        Function(e As WorkflowApplicationUnhandledExceptionEventArgs)
            Console.WriteLine(e.UnhandledException)
            Return UnhandledExceptionAction.Terminate
        End Function

    wfApp.Idle = _
        Sub(e As WorkflowApplicationIdleEventArgs)
            idleEvent.Set()
        End Sub

    wfApp.Run()

    ' Loop until the workflow completes.
    Dim waitHandles As WaitHandle() = New WaitHandle() {syncEvent, idleEvent}
    Do While WaitHandle.WaitAny(waitHandles) <> 0
        'Gather the user input and resume the bookmark.
        Dim validEntry As Boolean = False
        Do While validEntry = False
            Dim Guess As Integer
            If Int32.TryParse(Console.ReadLine(), Guess) = False Then
                Console.WriteLine("Please enter an integer.")
            Else
                validEntry = True
                wfApp.ResumeBookmark("EnterGuess", Guess)
            End If
        Loop
    Loop
End Sub
static void Main(string[] args)
{
    AutoResetEvent syncEvent = new AutoResetEvent(false);
    AutoResetEvent idleEvent = new AutoResetEvent(false);

    var inputs = new Dictionary<string, object>() { { "MaxNumber", 100 } };

    WorkflowApplication wfApp =
        new WorkflowApplication(new Workflow1(), inputs);

    wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
    {
        int Turns = Convert.ToInt32(e.Outputs["Turns"]);
        Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns);

        syncEvent.Set();
    };

    wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
    {
        Console.WriteLine(e.Reason);
        syncEvent.Set();
    };

    wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
    {
        Console.WriteLine(e.UnhandledException.ToString());
        return UnhandledExceptionAction.Terminate;
    };

    wfApp.Idle = delegate(WorkflowApplicationIdleEventArgs e)
    {
        idleEvent.Set();
    };

    wfApp.Run();

    // Loop until the workflow completes.
    WaitHandle[] handles = new WaitHandle[] { syncEvent, idleEvent };
    while (WaitHandle.WaitAny(handles) != 0)
    {
        // Gather the user input and resume the bookmark.
        bool validEntry = false;
        while (!validEntry)
        {
            int Guess;
            if (!Int32.TryParse(Console.ReadLine(), out Guess))
            {
                Console.WriteLine("Please enter an integer.");
            }
            else
            {
                validEntry = true;
                wfApp.ResumeBookmark("EnterGuess", Guess);
            }
        }
    }
}

另請參閱

工作

HOW TO:建立工作流程
HOW TO:建立與執行長期執行的工作流程

參考

WorkflowApplication
Bookmark

其他資源

Windows Workflow Foundation 程式設計
使用者入門教學課程
在工作流程中等待輸入
裝載工作流程