Sdílet prostřednictvím


Postupy: Spuštění pracovního postupu

Toto téma je pokračováním kurzu Začínáme se službou Windows Workflow Foundation a popisuje, jak vytvořit hostitele pracovního postupu a spustit pracovní postup definovaný v předchozím postupu: Vytvoření tématu pracovního postupu .

Poznámka:

Každé téma v kurzu Začínáme závisí na předchozích tématech. Chcete-li dokončit toto téma, musíte nejprve dokončit postupy: Vytvoření aktivity a postupy: Vytvoření pracovního postupu.

Vytvoření hostitelského projektu pracovního postupu

  1. Otevřete řešení z předchozího postupu: Vytvoření tématu aktivity pomocí sady Visual Studio 2012.

  2. Pravým tlačítkem myši klikněte na řešení WF45GettingStartedTutorial v Průzkumník řešení a vyberte Přidat nový projekt.

    Tip

    Pokud se okno Průzkumník řešení nezobrazí, v nabídce Zobrazit vyberte Průzkumník řešení.

  3. V nainstalovaném uzlu vyberte Visual C#, Workflow (nebo Visual Basic, Workflow).

    Poznámka:

    V závislosti na tom, který programovací jazyk je nakonfigurován jako primární jazyk v sadě Visual Studio, může být uzel Visual C# nebo Visual Basic pod uzlem Jiné jazyky v nainstalovaném uzlu.

    Ujistěte se, že je v rozevíracím seznamu verze rozhraní .NET Framework 4.5 vybraná možnost .NET Framework. V seznamu pracovních postupů vyberte konzolovou aplikaci pracovního postupu. Zadejte NumberGuessWorkflowHost do pole Název a klepněte na tlačítko OK. Tím se vytvoří úvodní aplikace pracovního postupu se základní podporou hostování pracovních postupů. Tento základní kód hostování se upraví a použije se ke spuštění aplikace pracovního postupu.

  4. Pravým tlačítkem myši klikněte na nově přidaný projekt NumberGuessWorkflowHost v Průzkumník řešení a vyberte Přidat odkaz. V seznamu Přidat odkaz vyberte Řešení, zaškrtněte políčko vedle NumberGuessWorkflowActivities a klikněte na tlačítko OK.

  5. V Průzkumník řešení klikněte pravým tlačítkem myši na Workflow1.xaml a zvolte Odstranit. Potvrďte kliknutím na tlačítko OK .

Úprava kódu hostování pracovního postupu

  1. Poklikáním na Program.cs nebo Module1.vb v Průzkumník řešení zobrazíte kód.

    Tip

    Pokud se okno Průzkumník řešení nezobrazí, v nabídce Zobrazit vyberte Průzkumník řešení.

    Protože byl tento projekt vytvořen pomocí šablony konzolové aplikace pracovního postupu, Program.cs nebo Module1.vb obsahuje následující základní kód hostování pracovního postupu.

    ' Create and cache the workflow definition.
    Dim workflow1 As Activity = New Workflow1()
    WorkflowInvoker.Invoke(workflow1)
    
    // Create and cache the workflow definition.
    Activity workflow1 = new Workflow1();
    WorkflowInvoker.Invoke(workflow1);
    

    Tento vygenerovaný kód hostování používá WorkflowInvoker. WorkflowInvoker poskytuje jednoduchý způsob, jak vyvolat pracovní postup, jako by se jednalo o volání metody a lze jej použít pouze pro pracovní postupy, které nepoužívají trvalost. WorkflowApplication poskytuje bohatší model pro provádění pracovních postupů, které zahrnují oznámení událostí životního cyklu, řízení provádění, obnovení záložky a trvalost. Tento příklad používá záložky a WorkflowApplication používá se k hostování pracovního postupu. Na začátek Program.cs nebo Module1.vb pod existující příkazy using nebo Imports přidejte následující using příkaz nebo Imports.

    Imports NumberGuessWorkflowActivities
    Imports System.Threading
    
    using NumberGuessWorkflowActivities;
    using System.Threading;
    

    Nahraďte řádky kódu, které používají WorkflowInvoker následující základní WorkflowApplication kód hostování. Tento ukázkový kód hostování ukazuje základní kroky pro hostování a vyvolání pracovního postupu, ale zatím neobsahuje funkce pro úspěšné spuštění pracovního postupu z tohoto tématu. V následujících krocích se tento základní kód upraví a do dokončení aplikace se přidají další funkce.

    Poznámka:

    V těchto příkladech je nutné nahradit textem , nebo v závislosti na tom, který pracovní postup jste dokončili v předchozím kroku Postupy: Vytvoření pracovního postupu.StateMachineNumberGuessWorkflowSequentialNumberGuessWorkflowFlowchartNumberGuessWorkflowWorkflow1 Pokud nenahrazujete Workflow1 , při pokusu o sestavení nebo spuštění pracovního postupu se zobrazí chyby sestavení.

    AutoResetEvent syncEvent = new AutoResetEvent(false);
    
    WorkflowApplication wfApp =
        new WorkflowApplication(_wf);
    
    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();
    
    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()
    

    Tento kód vytvoří , přihlásí se k odběru WorkflowApplicationtří událostí životního cyklu pracovního postupu, spustí pracovní postup voláním Runa pak čeká na dokončení pracovního postupu. Po dokončení AutoResetEvent pracovního postupu se nastaví a hostitelská aplikace se dokončí.

Nastavení vstupních argumentů pracovního postupu

  1. Na začátek Program.cs nebo Module1.vb pod existující using příkazy nebo Imports příkazy přidejte následující příkaz.

  2. Nahraďte řádek kódu, který vytvoří nový WorkflowApplication následujícím kódem, který vytvoří a předá slovník parametrů pracovnímu postupu při jeho vytvoření.

    Poznámka:

    V těchto příkladech nahraďte textem , nebo v závislosti na tom, který pracovní postup jste dokončili v předchozím kroku Postupy: Vytvoření pracovního postupu.StateMachineNumberGuessWorkflowSequentialNumberGuessWorkflowFlowchartNumberGuessWorkflowWorkflow1 Pokud nenahrazujete Workflow1 , při pokusu o sestavení nebo spuštění pracovního postupu se zobrazí chyby sestavení.

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

    Tento slovník obsahuje jeden prvek s klíčem MaxNumber. Klíče ve vstupním slovníku odpovídají vstupním argumentům kořenové aktivity pracovního postupu. MaxNumber používá pracovní postup k určení horní hranice náhodně vygenerovaného čísla.

Načtení výstupních argumentů pracovního postupu

  1. Upravte obslužnou rutinu Completed tak, aby načetla a zobrazila počet otočení používaných pracovním postupem.

    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.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
    

Obnovení záložky

  1. Do horní části Main metody přidejte následující kód těsně za existující AutoResetEvent deklaraci.

    AutoResetEvent idleEvent = new AutoResetEvent(false);
    
    Dim idleEvent As New AutoResetEvent(False)
    
  2. Přidejte následující Idle obslužnou rutinu těsně pod existující tři obslužné rutiny životního cyklu pracovního postupu v souboru Main.

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

    Pokaždé, když se pracovní postup změní na nečinné čekání na další odhad, zavolá se tato obslužná rutina a nastaví se idleAction AutoResetEvent . Kód v následujícím kroku použije idleEvent a syncEvent určí, jestli pracovní postup čeká na další odhad nebo je dokončený.

    Poznámka:

    V tomto příkladu hostitelská aplikace používá události automatického resetování v Completed obslužných Idle rutinách k synchronizaci hostitelské aplikace s průběhem pracovního postupu. Před obnovením záložky není nutné blokovat a čekat na nečinnost pracovního postupu, ale v tomto příkladu jsou vyžadovány události synchronizace, aby hostitel věděl, zda je pracovní postup dokončen nebo zda čeká na více uživatelských vstupů pomocí nástroje Bookmark. Další informace najdete v tématu Záložky.

  3. Odeberte volání WaitOnea nahraďte ho kódem, který shromáždí vstup od uživatele a obnoví .Bookmark

    Odeberte následující řádek kódu.

    syncEvent.WaitOne();
    
    syncEvent.WaitOne()
    

    Nahraďte ho následujícím příkladem.

    // 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)
        {
            if (!Int32.TryParse(Console.ReadLine(), out int Guess))
            {
                Console.WriteLine("Please enter an integer.");
            }
            else
            {
                validEntry = true;
                wfApp.ResumeBookmark("EnterGuess", Guess);
            }
        }
    }
    
    ' 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
    

Sestavení a spuštění aplikace

  1. Klikněte pravým tlačítkem na NumberGuessWorkflowHost v Průzkumník řešení a vyberte Nastavit jako spouštěcí projekt.

  2. Stisknutím kombinace kláves CTRL+F5 sestavte a spusťte aplikaci. Zkuste číslo odhadnout co nejvíce.

    Chcete-li aplikaci vyzkoušet s jedním z dalších stylů pracovního postupu, nahraďte Workflow1 v kódu, který vytváří WorkflowApplication FlowchartNumberGuessWorkflowznak , SequentialNumberGuessWorkflownebo StateMachineNumberGuessWorkflow, v závislosti na tom, který styl pracovního postupu chcete.

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

    Pokyny k přidání trvalosti do aplikace pracovního postupu najdete v dalším tématu Postupy : Vytvoření a spuštění dlouhotrvajícího pracovního postupu.

Příklad

Následující příklad je úplný výpis kódu pro metodu Main .

Poznámka:

V těchto příkladech nahraďte textem , nebo v závislosti na tom, který pracovní postup jste dokončili v předchozím kroku Postupy: Vytvoření pracovního postupu.StateMachineNumberGuessWorkflowSequentialNumberGuessWorkflowFlowchartNumberGuessWorkflowWorkflow1 Pokud nenahrazujete Workflow1 , při pokusu o sestavení nebo spuštění pracovního postupu se zobrazí chyby sestavení.

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(_wf, inputs)
    {

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

            syncEvent.Set();
        },

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

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

        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)
        {
            if (!Int32.TryParse(Console.ReadLine(), out int Guess))
            {
                Console.WriteLine("Please enter an integer.");
            }
            else
            {
                validEntry = true;
                wfApp.ResumeBookmark("EnterGuess", Guess);
            }
        }
    }
}
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

Viz také