Dela via


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

  1. Ö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).

  2. 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 Explorermenyn Visa.

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

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

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

  1. 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 Explorermenyn 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. SequentialNumberGuessWorkflowFlowchartNumberGuessWorkflowWorkflow1 Om du inte ersätter Workflow1 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

  1. Lägg till följande -instruktion överst i Program.cs eller Module1.vb under befintliga using eller Imports instruktioner.

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

    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

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

  1. 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)
    
  2. 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änder idleEvent och syncEvent 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.

  3. Ta bort anropet till WaitOneoch 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

  1. Högerklicka på NumberGuessWorkflowHost i Solution Explorer och välj Ange som startprojekt.

  2. 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 med FlowchartNumberGuessWorkflow, SequentialNumberGuessWorkfloweller StateMachineNumberGuessWorkflow, 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

Se även