Gör så här: Kör ett arbetsflöde
Det här avsnittet är en fortsättning på självstudiekursen om Windows Workflow Foundation Komma igång och beskriver hur du skapar en arbetsflödesvärd och kör arbetsflödet som definierades i föregående how to: Create a Workflow topic (Skapa ett arbetsflöde).
Kommentar
Varje ämne i självstudiekursen Komma igång beror på föregående avsnitt. För att slutföra det här avsnittet måste du först slutföra Så här: Skapa en aktivitet och Så här skapar du ett arbetsflöde.
Så här skapar du arbetsflödets värdprojekt
Öppna lösningen från föregående How to: Create an Activity topic by using Visual Studio 2012 (Skapa en aktivitet med hjälp av Visual Studio 2012).
Högerklicka på lösningen WF45GettingStartedTutorial i Solution Explorer och välj Lägg till, Nytt projekt.
Dricks
Om Solution Explorer-fönstret inte visas väljer du Solution Explorer på menyn Visa.
I noden Installerad väljer du Visual C#, Workflow (eller Visual Basic, Workflow).
Kommentar
Beroende på vilket programmeringsspråk som konfigureras som primärt språk i Visual Studio kan noden Visual C# eller Visual Basic finnas under noden Andra språk i noden Installerad .
Kontrollera att .NET Framework 4.5 är markerat i listrutan .NET Framework-version. Välj Arbetsflödeskonsolprogram i listan Arbetsflöde . Skriv
NumberGuessWorkflowHost
i rutan Namn och klicka på OK. Detta skapar ett startarbetsflödesprogram med grundläggande arbetsflödesvärdstöd. Den här grundläggande värdkoden ändras och används för att köra arbetsflödesprogrammet.Högerklicka på det nyligen tillagda Projektet NumberGuessWorkflowHost i Solution Explorer och välj Lägg till referens. Välj Lösning i listan Lägg till referens , markera kryssrutan bredvid NumberGuessWorkflowActivities och klicka sedan på OK.
Högerklicka på Workflow1.xaml i Solution Explorer och välj Ta bort. Bekräfta genom att klicka på OK .
Ändra arbetsflödets värdkod
Dubbelklicka på Program.cs eller Module1.vb i Solution Explorer för att visa koden.
Dricks
Om Solution Explorer-fönstret inte visas väljer du Solution Explorer på menyn Visa.
Eftersom det här projektet skapades med hjälp av mallen För arbetsflödeskonsolen innehåller Program.cs eller Module1.vb följande grundläggande arbetsflödesvärdkod.
' 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);
Den här genererade värdkoden använder WorkflowInvoker. WorkflowInvoker ger ett enkelt sätt att anropa ett arbetsflöde som om det vore ett metodanrop och kan endast användas för arbetsflöden som inte använder beständighet. WorkflowApplication tillhandahåller en mer omfattande modell för att köra arbetsflöden som innehåller meddelanden om livscykelhändelser, körningskontroll, återupptagande av bokmärken och beständighet. Det här exemplet använder bokmärken och WorkflowApplication används som värd för arbetsflödet. Lägg till följande
using
instruktion eller Import-instruktion överst i Program.cs eller Module1.vb under de befintliga användnings - eller importinstruktionerna .Imports NumberGuessWorkflowActivities Imports System.Threading
using NumberGuessWorkflowActivities; using System.Threading;
Ersätt kodraderna som använder WorkflowInvoker med följande grundläggande WorkflowApplication värdkod. Det här exemplet på värdkod visar de grundläggande stegen för att vara värd för och anropa ett arbetsflöde, men innehåller ännu inte funktionerna för att köra arbetsflödet från det här avsnittet. I följande steg ändras den här grundläggande koden och ytterligare funktioner läggs till tills programmet har slutförts.
Kommentar
I de här exemplen måste du ersätta med , eller
StateMachineNumberGuessWorkflow
, beroende på vilket arbetsflöde du slutförde i föregående Steg för att: Skapa ett arbetsflöde.SequentialNumberGuessWorkflow
FlowchartNumberGuessWorkflow
Workflow1
Om du inte ersätterWorkflow1
får du byggfel när du försöker skapa eller köra arbetsflödet.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()
Den här koden skapar en WorkflowApplication, prenumererar på tre livscykelhändelser för arbetsflödet, startar arbetsflödet med ett anrop till Runoch väntar sedan på att arbetsflödet ska slutföras. När arbetsflödet har slutförts AutoResetEvent anges och värdprogrammet slutförs.
Ange indataargument för ett arbetsflöde
Lägg till följande -instruktion överst i Program.cs eller Module1.vb under befintliga
using
ellerImports
instruktioner.Ersätt den kodrad som skapar den nya WorkflowApplication med följande kod som skapar och skickar en ordlista med parametrar till arbetsflödet när den skapas.
Kommentar
Ersätt
Workflow1
i de här exemplen medFlowchartNumberGuessWorkflow
,SequentialNumberGuessWorkflow
, ellerStateMachineNumberGuessWorkflow
, beroende på vilket arbetsflöde du slutförde i föregående Steg för att: Skapa ett arbetsflöde . Om du inte ersätterWorkflow1
får du byggfel när du försöker skapa eller köra arbetsflödet.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)
Den här ordlistan innehåller ett element med nyckeln
MaxNumber
. Nycklar i indataordlistan motsvarar indataargument för arbetsflödets rotaktivitet.MaxNumber
används av arbetsflödet för att fastställa den övre gränsen för det slumpmässigt genererade talet.
Så här hämtar du utdataargument för ett arbetsflöde
Completed Ändra hanteraren för att hämta och visa antalet svängar som används av arbetsflödet.
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
Så här återupptar du ett bokmärke
Lägg till följande kod överst i
Main
metoden strax efter den befintliga AutoResetEvent deklarationen.AutoResetEvent idleEvent = new AutoResetEvent(false);
Dim idleEvent As New AutoResetEvent(False)
Lägg till följande Idle hanterare precis under de befintliga tre arbetsflödeslivscykelhanterare i
Main
.Idle = delegate (WorkflowApplicationIdleEventArgs e) { idleEvent.Set(); } };
wfApp.Idle = Sub(e As WorkflowApplicationIdleEventArgs) idleEvent.Set() End Sub
Varje gång arbetsflödet blir inaktivt i väntan på nästa gissning anropas den här hanteraren och
idleAction
AutoResetEvent anges. Koden i följande steg använderidleEvent
ochsyncEvent
för att avgöra om arbetsflödet väntar på nästa gissning eller är klar.Kommentar
I det här exemplet använder värdprogrammet automatiska återställningshändelser i Completed och-hanterare Idle för att synkronisera värdprogrammet med arbetsflödets förlopp. Det är inte nödvändigt att blockera och vänta tills arbetsflödet blir inaktivt innan ett bokmärke återupptas, men i det här exemplet krävs synkroniseringshändelserna så att värden vet om arbetsflödet är klart eller om det väntar på fler användarindata med hjälp Bookmarkav . Mer information finns i Bokmärken.
Ta bort anropet till
WaitOne
och ersätt det med kod för att samla in indata från användaren och återuppta Bookmark.Ta bort följande kodrad.
syncEvent.WaitOne();
syncEvent.WaitOne()
Ersätt den med följande exempel.
// 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
Skapa och köra programmet
Högerklicka på NumberGuessWorkflowHost i Solution Explorer och välj Ange som startprojekt.
Tryck på CTRL+F5 för att skapa och köra programmet. Försök att gissa talet i så få svängar som möjligt.
Om du vill prova programmet med någon av de andra arbetsflödesformaten ersätter
Workflow1
du i koden som skapar WorkflowApplication medFlowchartNumberGuessWorkflow
,SequentialNumberGuessWorkflow
ellerStateMachineNumberGuessWorkflow
, beroende på vilket arbetsflödesformat du vill ha.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)
Anvisningar om hur du lägger till beständighet i ett arbetsflödesprogram finns i nästa avsnitt: Skapa och köra ett tidskrävande arbetsflöde.
Exempel
Följande exempel är den fullständiga kodlistan för Main
metoden.
Kommentar
Ersätt Workflow1
i de här exemplen med FlowchartNumberGuessWorkflow
, SequentialNumberGuessWorkflow
, eller StateMachineNumberGuessWorkflow
, beroende på vilket arbetsflöde du slutförde i föregående Steg för att: Skapa ett arbetsflöde . Om du inte ersätter Workflow1
får du byggfel när du försöker skapa eller köra arbetsflödet.
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