Vorgehensweise: Ausführen eines Workflows
Dieses Thema gilt für Windows Workflow Foundation 4.
Dieses Thema ist eine Fortsetzung des Themas "Windows Workflow Foundation: Erste Schritte". Darin wird beschrieben, wie Sie den im vorherigen Thema Vorgehensweise: Erstellen eines Workflows definierten Workflow ausführen.
Hinweis: |
---|
Ein Thema im Lernprogramm "Erste Schritte" hängt jeweils von den vorherigen Themen ab. Um dieses Thema verwenden zu können, müssen Sie zuerst Vorgehensweise: Erstellen einer Aktivität und Vorgehensweise: Erstellen eines Workflows durcharbeiten und abschließen. |
So öffnen Sie das Workflowhostprojekt
Öffnen Sie die Projektmappe des vorherigen Themas Vorgehensweise: Erstellen eines Workflows mit Visual Studio 2010.
Doppelklicken Sie im Projektmappen-Explorer auf Program.cs oder Module1.vb, um den Code anzuzeigen.
Tipp: Wenn das Fenster Projektmappen-Explorer nicht angezeigt wird, wählen Sie im Menü Ansicht die Option Projektmappen-Explorer aus. Da dieses Projekt mit der Vorlage Konsolenanwendung für Workflows erstellt wurde, enthält Program.cs oder Module1.vb den folgenden grundlegenden Code zum Hosten von Workflows.
WorkflowInvoker.Invoke(New Workflow1())
WorkflowInvoker.Invoke(new Workflow1());
Dieser generierte Hostingcode verwendet das WorkflowInvoker-Element. Das WorkflowInvoker-Element stellt eine einfache Möglichkeit zum Aufrufen eines Workflows dar, als ob es sich dabei um einen Methodenaufruf handeln würde, und es kann nur für Workflows verwendet werden, die keine Persistenz nutzen. WorkflowApplication bietet ein umfangreicheres Modell zum Ausführen von Workflows mit Benachrichtigung über Lebenszyklusereignisse, Ausführungssteuerung, Wiederaufnahme von Lesezeichen und Persistenz. In diesem Beispiel werden Lesezeichen verwendet, und WorkflowApplication wird zum Hosten des Workflows genutzt. Fügen Sie die folgende using- oder Imports-Anweisung am Anfang vonProgram.cs oder Module1.vb unter der vorhandenen using- oder Imports-Anweisung hinzu.
Imports System.Threading
using System.Threading;
Ersetzen Sie die Codezeile, in der WorkflowInvoker mit dem folgenden grundlegenden WorkflowApplication-Hostingcode verwendet wird. In diesem Beispielhostingcode werden die grundlegenden Schritte zum Hosten und das Aufrufen eines Workflows veranschaulicht, das Beispiel enthält jedoch noch nicht die Funktionalität zum erfolgreichen Ausführen des Workflows aus diesem Thema. In den folgenden Schritten wird der grundlegende Code geändert, und es werden zusätzliche Funktionen hinzugefügt, bis die Anwendung abgeschlossen wurde.
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();
In diesem Code wird ein WorkflowApplication-Element erstellt, es werden drei Lebenszyklusereignisse des Workflows abonniert, der Workflow wird per Aufruf von Run gestartet, und dann wird auf den Abschluss des Workflows gewartet. Nach Abschluss des Workflows wird AutoResetEvent festgelegt, und die Hostanwendung wird abgeschlossen.
So legen Sie die Eingabeargumente eines Workflows fest
Fügen Sie oben in der Datei Program.cs oder Module1.vb unter den vorhandenen using- oder Imports-Anweisung die folgende Anweisung hinzu.
Imports System.Collections.Generic
using System.Collections.Generic;
Ersetzen Sie die Codezeile, die das neue WorkflowApplication-Element erstellt, durch den folgenden Code, der ein Wörterbuch mit Parametern erstellt und dieses nach seiner Erstellung an den Workflow übergibt.
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);
Dieses Wörterbuch enthält ein Element mit dem Schlüssel
MaxNumber
. Die Schlüssel im Eingabewörterbuch entsprechen den Eingabeargumenten der Stammaktivität des Workflows.MaxNumber
wird vom Workflow verwendet, um die Obergrenze für die zufällig generierte Zahl zu bestimmen.
So rufen Sie die Ausgabeargumente eines Workflows ab
Ändern Sie den Completed-Handler, um die Anzahl der vom Workflow verwendeten Durchgänge (turns) abzurufen und anzuzeigen.
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(); };
So nehmen Sie ein Lesezeichen wieder auf
Fügen Sie oben in der
Main
-Methode direkt nach der bestehenden AutoResetEvent-Deklaration den folgenden Code hinzu.Dim idleEvent As New AutoResetEvent(False)
AutoResetEvent idleEvent = new AutoResetEvent(false);
Fügen Sie direkt unterhalb der drei bestehenden Lebenszyklushandler des Workflows im Abschnitt
Main
den folgenden Idle-Handler hinzu.wfApp.Idle = _ Sub(e As WorkflowApplicationIdleEventArgs) idleEvent.Set() End Sub
wfApp.Idle = delegate(WorkflowApplicationIdleEventArgs e) { idleEvent.Set(); };
Immer wenn der Workflow dann in den Leerlaufzustand eintritt und auf den nächsten Lösungsversuch wartet, wird dieser Handler aufgerufen und
idleAction
AutoResetEvent festgelegt. Der Code im folgenden Schritt verwendetidleEvent
undsyncEvent
, um zu ermitteln, ob der Workflow auf den nächsten Lösungsversuch wartet oder abgeschlossen ist.Hinweis: In diesem Beispiel verwendet die Hostanwendung AutoReset-Ereignisse in den Handlern Completed und Idle, um die Hostanwendung mit dem Status des Workflows zu synchronisieren. Das Blockieren und das Warten auf den Eintritt des Workflows in den Leerlaufzustand ist nicht erforderlich, bevor ein Lesezeichen wiederaufgenommen wird. In diesem Beispiel sind die Synchronisierungsereignisse jedoch erforderlich, damit der Host weiß, ob der Workflow abgeschlossen ist oder ob dieser mithilfe von Bookmark auf weitere Benutzereingaben wartet. Weitere Informationen finden Sie unter Lesezeichen. Entfernen Sie den Aufruf von WaitOne, und ersetzen Sie diesen durch Code zum Erfassen der Eingabe des Benutzers und zum Wiederaufnehmen von Bookmark.
Entfernen Sie die folgende Codezeile.
syncEvent.WaitOne()
syncEvent.WaitOne();
Ersetzen Sie diese durch den folgenden Beispielcode.
' 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); } } }
So erstellen Sie die Anwendung und führen diese aus
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf WorkflowConsoleApplication1, und wählen Sie Als Startprojekt festlegen aus.
Drücken Sie STRG+F5, um die Anwendung zu erstellen und auszuführen. Versuchen Sie, die Zahl in möglichst wenigen Durchgängen zu erraten.
Eine Anleitung dazu, wie Sie einer Workflowanwendung Persistenz hinzufügen, finden Sie im nächsten Thema: Vorgehensweise: Erstellen und Ausführen eines Workflows mit langer Laufzeit.
Beispiel
Das folgende Beispiel ist die vollständige Codeauflistung für die Main
-Methode.
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);
}
}
}
}
Siehe auch
Aufgaben
Vorgehensweise: Erstellen eines Workflows
Vorgehensweise: Erstellen und Ausführen eines Workflows mit langer Laufzeit
Verweis
Weitere Ressourcen
Windows Workflow Foundation-Programmierung
Lernprogramm "Erste Schritte "
Warten auf Eingabe in einem Workflow
Hosten von Workflows