Partager via


Procédure : exécuter un workflow

Cette rubrique s'applique à Windows Workflow Foundation 4.

Cette rubrique est une suite du didacticiel Mise en route de Windows Workflow Foundation et explique comment exécuter le workflow défini dans la rubrique Procédure : créer un workflow précédente.

Dd489463.note(fr-fr,VS.100).gifRemarque :
Chaque rubrique du didacticiel de mise en route dépend des rubriques précédentes. Pour effectuer cette rubrique, vous devez d'abord effectuer Procédure : créer une activité et Procédure : créer un workflow.

Pour ouvrir le projet hôte du workflow

  1. Ouvrez la solution de la rubrique Procédure : créer un workflow précédente à l'aide de Visual Studio 2010.

  2. Double-cliquez sur Program.cs ou sur Module1.vb dans l'Explorateur de solutions pour afficher le code.

    Dd489463.Tip(fr-fr,VS.100).gifConseil :
    Si la fenêtre Explorateur de solutions n'est pas affichée, sélectionnez Explorateur de solutions dans le menu Affichage.

    Étant donné que ce projet a été créé à l'aide du modèle Application console de workflow, Program.cs ou Module1.vb contient le code d'hébergement de workflow de base suivant.

    WorkflowInvoker.Invoke(New Workflow1())
    
    WorkflowInvoker.Invoke(new Workflow1());
    

    Ce code d'hébergement généré utilise WorkflowInvoker. WorkflowInvoker offre un moyen simple pour appeler un workflow comme s'il s'agissait d'un appel de méthode et peut être utilisé uniquement pour les workflows qui n'utilisent pas la persistance. WorkflowApplication fournit un modèle plus riche pour l'exécution des workflows, lequel inclut la notification des événements de cycle de vie, le contrôle d'exécution, la reprise de signet et la persistance. Cet exemple utilise des signets et WorkflowApplication est utilisé pour l'hébergement du workflow. Ajoutez l'instruction using ou Imports suivante dans la partie supérieure de Program.cs ou Module1.vb sous les instructions using ou Imports existantes.

    Imports System.Threading
    
    using System.Threading;
    

    Remplacez la ligne de code qui utilise WorkflowInvoker par le code d'hébergement WorkflowApplication de base suivant. Cet exemple de code d'hébergement montre les étapes de base pour l'hébergement et l'appel d'un workflow, mais ne contient pas encore les fonctionnalités pour exécuter avec succès le workflow à partir de cette rubrique. Au cours des étapes suivantes, le code de base est modifié et des fonctionnalités supplémentaires sont ajoutées jusqu'à ce que l'application soit terminée.

    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();
    

    Ce code crée un WorkflowApplication, s'abonne à trois événements de cycle de vie du workflow, démarre le workflow avec un appel à la méthode Run, puis attend que le workflow soit terminé. Lorsque le workflow est terminé, le AutoResetEvent est défini et l'application hôte se termine.

Pour définir des arguments d'entrée d'un workflow

  1. Ajoutez l'instruction suivante dans la partie supérieure de Program.cs ou Module1.vb sous les instructions using ou Imports existantes.

    Imports System.Collections.Generic
    
    using System.Collections.Generic;
    
  2. Remplacez la ligne de code qui crée le WorkflowApplication par le code suivant qui crée et passe un dictionnaire de paramètres au workflow lorsqu'il est créé.

    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);
    

    Ce dictionnaire contient un élément avec une clé de MaxNumber. Les clés figurant dans le dictionnaire d'entrée correspondent aux arguments d'entrée sur l'activité racine du workflow. MaxNumber est utilisé par le workflow pour déterminer la limite supérieure du nombre généré aléatoirement.

Pour récupérer des arguments de sortie d'un workflow

  1. Modifiez le gestionnaire Completed pour récupérer et afficher le nombre de tours utilisé par le workflow.

    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();
    };
    

Pour reprendre un signet

  1. Ajoutez le code suivant en haut de la méthode Main, juste après la déclaration AutoResetEvent existante.

    Dim idleEvent As New AutoResetEvent(False)
    
    AutoResetEvent idleEvent = new AutoResetEvent(false);
    
  2. Ajoutez le gestionnaire Idle suivant, juste en dessous des trois gestionnaires de cycle de vie du workflow existants dans Main.

    wfApp.Idle = _
        Sub(e As WorkflowApplicationIdleEventArgs)
            idleEvent.Set()
        End Sub
    
    wfApp.Idle = delegate(WorkflowApplicationIdleEventArgs e)
    {
        idleEvent.Set();
    };
    

    Chaque fois que le workflow reste inactif dans l'attente de l'estimation suivante, ce gestionnaire est appelé et le AutoResetEventidleAction est défini. Le code de l'étape suivante utilise idleEvent et syncEvent pour déterminer si le workflow attend l'estimation suivante ou s'il est terminé.

    Dd489463.note(fr-fr,VS.100).gifRemarque :
    Dans cet exemple, l'application hôte utilise des événements à réinitialisation automatique dans les gestionnaires Idle et Completed pour synchroniser l'application hôte avec la progression du workflow. Il n'est pas nécessaire de bloquer et d'attendre que le workflow devienne inactif avant de reprendre un signet mais, dans cet exemple, les événements de synchronisation sont nécessaires afin que l'hôte sache si le workflow est terminé ou s'il attend une ou plusieurs autres entrées d'utilisateur à l'aide de Bookmark. Pour plus d'informations, consultez Signets.

  3. Supprimez l'appel à WaitOne et remplacez-le par du code pour recueillir l'entrée de l'utilisateur et reprendre le Bookmark.

    Supprimez la ligne de code suivante.

    syncEvent.WaitOne()
    
    syncEvent.WaitOne();
    

    Remplacez-la par l'exemple suivant.

    ' 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);
            }
        }
    }
    

Pour générer et exécuter l'application

  1. Cliquez avec le bouton droit sur WorkflowConsoleApplication1 dans l'Explorateur de solutions, puis sélectionnez Définir comme projet de démarrage.

  2. Appuyez sur CTRL+F5 pour générer et exécuter l'application. Essayez de deviner le nombre en aussi peu de tours que possible.

    Pour obtenir des instructions sur la façon d'ajouter de la persistance à une application de workflow, consultez la rubrique suivante, Procédure : créer et exécuter un workflow de longue durée.

Exemple

L'exemple suivant constitue l'intégralité du code de la méthode Main.

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);
            }
        }
    }
}

Voir aussi

Tâches

Procédure : créer un workflow
Procédure : créer et exécuter un workflow de longue durée

Référence

WorkflowApplication
Bookmark

Autres ressources

Programmation Windows Workflow Foundation
Didacticiel de mise en route
Attente d'une entrée dans un flux de travail
Hébergement de workflows