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
Otevřete řešení z předchozího postupu: Vytvoření tématu aktivity pomocí sady Visual Studio 2012.
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í.
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.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.
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
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.
StateMachineNumberGuessWorkflow
SequentialNumberGuessWorkflow
FlowchartNumberGuessWorkflow
Workflow1
Pokud nenahrazujeteWorkflow1
, 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
Na začátek Program.cs nebo Module1.vb pod existující
using
příkazy neboImports
příkazy přidejte následující příkaz.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.
StateMachineNumberGuessWorkflow
SequentialNumberGuessWorkflow
FlowchartNumberGuessWorkflow
Workflow1
Pokud nenahrazujeteWorkflow1
, 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
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
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)
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žijeidleEvent
asyncEvent
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.
Odeberte volání
WaitOne
a nahraďte ho kódem, který shromáždí vstup od uživatele a obnoví .BookmarkOdeberte 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
Klikněte pravým tlačítkem na NumberGuessWorkflowHost v Průzkumník řešení a vyberte Nastavit jako spouštěcí projekt.
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áří WorkflowApplicationFlowchartNumberGuessWorkflow
znak ,SequentialNumberGuessWorkflow
neboStateMachineNumberGuessWorkflow
, 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.StateMachineNumberGuessWorkflow
SequentialNumberGuessWorkflow
FlowchartNumberGuessWorkflow
Workflow1
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