Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ten temat jest kontynuacją samouczka "Pierwsze kroki z Windows Workflow Foundation" i omawia, jak utworzyć hosta przepływu pracy oraz uruchomić przepływ pracy zdefiniowany w poprzednim temacie: Jak utworzyć przepływ pracy.
Uwaga
Każdy temat w samouczku „Pierwsze kroki” zależy od poprzednich tematów. Aby ukończyć to zagadnienie, należy najpierw wykonać Jak: Utworzyć działanie i Jak: Utworzyć przepływ pracy.
Aby utworzyć projekt hosta przepływu pracy
Otwórz rozwiązanie z poprzedniego tematu Porady: tworzenie tematu działania przy użyciu programu Visual Studio 2012.
Kliknij prawym przyciskiem myszy rozwiązanie WF45GettingStartedTutorial w Eksplorator rozwiązań i wybierz polecenie Dodaj nowy projekt.
Wskazówka
Jeśli okno Eksplorator rozwiązań nie jest wyświetlane, wybierz pozycję Eksplorator rozwiązań z menu Widok.
W węźle Zainstalowany wybierz pozycję Visual C#, Workflow (lub Visual Basic, Workflow).
Uwaga
W zależności od tego, który język programowania jest skonfigurowany jako język podstawowy w programie Visual Studio, węzeł Visual C# lub Visual Basic może znajdować się w węźle Inne języki w węźle Zainstalowane .
Upewnij się, że .NET Framework 4.5 został wybrany w rozwijanej liście wersji programu .NET Framework. Wybierz pozycję Aplikacja konsoli przepływu pracy z listy Przepływ pracy . Wpisz
NumberGuessWorkflowHostw polu Nazwa i kliknij przycisk OK. Spowoduje to utworzenie początkowej aplikacji przepływu pracy z podstawową obsługą hostingu przepływu pracy. Ten podstawowy kod hostingu jest modyfikowany i używany do uruchamiania aplikacji przepływu pracy.Kliknij prawym przyciskiem myszy nowo dodany projekt NumberGuessWorkflowHost w Eksplorator rozwiązań i wybierz polecenie Dodaj odwołanie. Wybierz pozycję Rozwiązanie z listy Dodaj odwołanie , zaznacz pole wyboru obok pozycji NumberGuessWorkflowActivities, a następnie kliknij przycisk OK.
Kliknij prawym przyciskiem myszy plik Workflow1.xaml w Eksplorator rozwiązań i wybierz polecenie Usuń. Kliknij przycisk OK , aby potwierdzić.
Aby zmodyfikować kod obsługi przepływu pracy
Kliknij dwukrotnie Program.cs lub Module1.vb w Eksplorator rozwiązań, aby wyświetlić kod.
Wskazówka
Jeśli okno Eksplorator rozwiązań nie jest wyświetlane, wybierz pozycję Eksplorator rozwiązań z menu Widok.
Ponieważ ten projekt został utworzony przy użyciu szablonu aplikacja konsoli przepływu pracy, Program.cs lub Module1.vb zawiera następujący podstawowy kod hostingu przepływu pracy.
' 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);Ten wygenerowany kod hostingu używa metody WorkflowInvoker. WorkflowInvoker Umożliwia prosty sposób wywołania przepływu pracy tak, jakby był to wywołanie metody, i można używać tylko w przypadku przepływów pracy, które nie używają zapisywania stanu. WorkflowApplication Udostępnia bogatszy model wykonywania przepływów pracy, który obejmuje powiadomienia o zdarzeniach cyklu życia, kontrolę wykonywania, wznowienie zakładek i utrwalanie. W tym przykładzie użyto zakładek, a WorkflowApplication jest używane do hostowania przepływu pracy. Dodaj następujące
usinglub Imports na początku Program.cs lub Module1.vb, poniżej istniejących using statements lub Imports.Imports NumberGuessWorkflowActivities Imports System.Threadingusing NumberGuessWorkflowActivities; using System.Threading;Zamień wiersze kodu, które używają WorkflowInvoker, na poniższy podstawowy kod hostingu WorkflowApplication. Ten przykładowy kod hostingu przedstawia podstawowe kroki hostowania i wywoływania przepływu pracy, ale nie zawiera jeszcze funkcji pomyślnego uruchomienia przepływu pracy z tego tematu. W poniższych krokach ten podstawowy kod jest modyfikowany, a dodatkowe funkcje są dodawane do momentu ukończenia aplikacji.
Uwaga
W tych przykładach należy zastąpić
Workflow1elementFlowchartNumberGuessWorkflow,SequentialNumberGuessWorkflowlubStateMachineNumberGuessWorkflow, w zależności od tego, który przepływ pracy został ukończony w poprzednim kroku Jak utworzyć przepływ pracy. Jeśli nie zastąpiszWorkflow1, podczas próby kompilacji lub uruchomienia przepływu pracy wystąpią błędy kompilacji.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()Ten kod tworzy WorkflowApplication, subskrybuje trzy zdarzenia cyklu życia przepływu pracy, uruchamia przepływ pracy przez wywołanie metody Run, a następnie czeka na zakończenie przepływu pracy. Po zakończeniu przepływu pracy zostanie ustawiona wartość AutoResetEvent, a aplikacja hosta kończy działanie.
Aby ustawić argumenty wejściowe przepływu pracy
Dodaj następującą instrukcję na początku Program.cs lub Module1.vb poniżej istniejących instrukcji
usinglubImports.Zastąp wiersz kodu, który tworzy nowy WorkflowApplication , następującym kodem, który tworzy i przekazuje słownik parametrów do przepływu pracy podczas jego tworzenia.
Uwaga
W tych przykładach zastąp
Workflow1ciągamiFlowchartNumberGuessWorkflow,SequentialNumberGuessWorkflowlubStateMachineNumberGuessWorkflow, w zależności od tego, który przepływ pracy ukończyłeś w poprzednim kroku Tworzenie Przepływu Pracy — Jak To Zrobić. Jeśli nie zastąpiszWorkflow1, podczas próby kompilacji lub uruchomienia przepływu pracy wystąpią błędy kompilacji.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)Ten słownik zawiera jeden element z kluczem
MaxNumber. Klucze w słowniku wejściowym odpowiadają argumentom wejściowym w działaniu głównym przepływu pracy.MaxNumberjest używany przez przepływ pracy do określenia górnej granicy dla losowo wygenerowanej liczby.
Aby pobrać argumenty wyjściowe przepływu pracy
Zmodyfikuj obsługiwacza Completed w celu pobrania i wyświetlenia liczby cykli używanych przez przepływ pracy.
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
Aby kontynuować zakładkę
Dodaj następujący kod w górnej części
Mainmetody tuż po istniejącej AutoResetEvent deklaracji.AutoResetEvent idleEvent = new AutoResetEvent(false);Dim idleEvent As New AutoResetEvent(False)Dodaj następującą Idle procedurę obsługi tuż poniżej istniejących trzech procedur obsługi cyklu życia przepływu pracy w programie
Main.Idle = delegate (WorkflowApplicationIdleEventArgs e) { idleEvent.Set(); } };wfApp.Idle = Sub(e As WorkflowApplicationIdleEventArgs) idleEvent.Set() End SubZa każdym razem, gdy przepływ pracy przechodzi w stan bezczynności w oczekiwaniu na następne odgadnięcie, ta procedura obsługi jest wywoływana i
idleActionAutoResetEvent jest ustawiane. Kod w poniższym kroku używaidleEventisyncEventdo określenia, czy przepływ pracy oczekuje na następne odgadnięcie, czy jest zakończony.Uwaga
W tym przykładzie aplikacja hosta używa automatycznie resetowanych zdarzeń w procedurach obsługi Completed i Idle w celu zsynchronizowania aplikacji hosta z postępem przepływu pracy. Nie jest konieczne blokowanie i oczekiwanie na bezczynność workflowu przed wznowieniem zakładki, ale w tym przykładzie zdarzenia synchronizacji są wymagane, aby host wiedział, czy workflow został ukończony, czy oczekuje na więcej danych wejściowych od użytkownika, korzystając z Bookmark. Aby uzyskać więcej informacji, zobacz Zakładki.
Usuń wywołanie metody
WaitOne, a następnie zastąp je kodem, aby zebrać dane wejściowe od użytkownika i wznowić proces Bookmark.Usuń następujący wiersz kodu.
syncEvent.WaitOne();syncEvent.WaitOne()Zastąp go poniższym przykładem.
// 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
Aby skompilować i uruchomić aplikację
Kliknij prawym przyciskiem myszy pozycję NumberGuessWorkflowHost w Eksplorator rozwiązań i wybierz pozycję Ustaw jako projekt startowy.
Naciśnij CTRL+F5, aby skompilować i uruchomić aplikację. Spróbuj odgadnąć liczbę w jak najmniejszej liczbie zakrętów.
Aby wypróbować aplikację przy użyciu jednego z innych stylów przepływu pracy, zastąp
Workflow1w kodzie, który tworzy WorkflowApplication, naFlowchartNumberGuessWorkflow,SequentialNumberGuessWorkflowlubStateMachineNumberGuessWorkflow, w zależności od tego, który styl przepływu pracy preferujesz.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)Aby uzyskać instrukcje dotyczące dodawania trwałości do aplikacji przepływu pracy, zobacz następny temat : Tworzenie i uruchamianie długotrwałego przepływu pracy.
Przykład
Poniższy przykład to kompletna lista kodu dla Main metody .
Uwaga
W tych przykładach zastąp Workflow1 ciągami FlowchartNumberGuessWorkflow, SequentialNumberGuessWorkflow lub StateMachineNumberGuessWorkflow, w zależności od tego, który przepływ pracy ukończyłeś w poprzednim kroku Tworzenie Przepływu Pracy — Jak To Zrobić. Jeśli nie zastąpisz Workflow1 , podczas próby kompilacji lub uruchomienia przepływu pracy wystąpią błędy kompilacji.
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