Workflow de contrôle dans les programmes Async (Visual Basic)Control Flow in Async Programs (Visual Basic)

Vous pouvez écrire et tenir à jour des programmes asynchrones plus facilement à l’aide des mots clés Async et Await.You can write and maintain asynchronous programs more easily by using the Async and Await keywords. Toutefois, les résultats peuvent vous étonner si vous ne comprenez pas le fonctionnement de votre programme.However, the results might surprise you if you don't understand how your program operates. Cette rubrique suit le flux de contrôle par le biais d’un programme asynchrone simple pour vous montrer quand le contrôle se déplace d’une méthode à une autre et quelles informations sont transférées à chaque fois.This topic traces the flow of control through a simple async program to show you when control moves from one method to another and what information is transferred each time.

Notes

Les mots clés Async et Await ont été introduits dans Visual Studio 2012.The Async and Await keywords were introduced in Visual Studio 2012.

En général, vous marquez les méthodes qui contiennent du code asynchrone avec le modificateur Async .In general, you mark methods that contain asynchronous code with the Async modifier. Dans une méthode marquée avec un modificateur Async, vous pouvez utiliser un opérateur await (Visual Basic) pour spécifier l’emplacement où la méthode s’interrompt pour attendre la fin d’un processus asynchrone appelé.In a method that's marked with an async modifier, you can use an Await (Visual Basic) operator to specify where the method pauses to wait for a called asynchronous process to complete. Pour plus d’informations, consultez programmation asynchrone avec Async et await (Visual Basic).For more information, see Asynchronous Programming with Async and Await (Visual Basic).

L’exemple suivant utilise des méthodes async pour télécharger le contenu d’un site web spécifié sous forme de chaîne et afficher la longueur de la chaîne.The following example uses async methods to download the contents of a specified website as a string and to display the length of the string. Il contient les deux méthodes suivantes.The example contains the following two methods.

  • startButton_Click, qui appelle AccessTheWebAsync et affiche le résultat.startButton_Click, which calls AccessTheWebAsync and displays the result.

  • AccessTheWebAsync, qui télécharge le contenu d’un site web sous forme de chaîne et retourne la longueur de la chaîne.AccessTheWebAsync, which downloads the contents of a website as a string and returns the length of the string. AccessTheWebAsync utilise une méthode asynchrone HttpClient, GetStringAsync(String), pour télécharger le contenu.AccessTheWebAsync uses an asynchronous HttpClient method, GetStringAsync(String), to download the contents.

Des lignes numérotées apparaissent à des points stratégiques du programme pour vous aider à comprendre comment le programme s’exécute et expliquer ce qui se produit à chaque point marqué.Numbered display lines appear at strategic points throughout the program to help you understand how the program runs and to explain what happens at each point that is marked. Les lignes sont étiquetées de "ONE" à "SIX".The display lines are labeled "ONE" through "SIX." Les étiquettes représentent l’ordre dans lequel le programme atteint ces lignes de code.The labels represent the order in which the program reaches these lines of code.

Le code suivant illustre un plan du programme.The following code shows an outline of the program.

Class MainWindow

    Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click

        ' ONE
        Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()

        ' FOUR
        Dim contentLength As Integer = Await getLengthTask

        ' SIX
        ResultsTextBox.Text &=
            String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)

    End Sub

    Async Function AccessTheWebAsync() As Task(Of Integer)

        ' TWO
        Dim client As HttpClient = New HttpClient()
        Dim getStringTask As Task(Of String) =
            client.GetStringAsync("https://msdn.microsoft.com")

        ' THREE
        Dim urlContents As String = Await getStringTask

        ' FIVE
        Return urlContents.Length
    End Function

End Class

Chacun des emplacements étiquetés de "ONE" à "SIX" affiche des informations sur l’état actuel du programme.Each of the labeled locations, "ONE" through "SIX," displays information about the current state of the program. La sortie suivante est produite :The following output is produced:

ONE:   Entering startButton_Click.
           Calling AccessTheWebAsync.

TWO:   Entering AccessTheWebAsync.
           Calling HttpClient.GetStringAsync.

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

Length of the downloaded string: 33946.

Configurer le programmeSet Up the Program

Vous pouvez télécharger le code que cette rubrique utilise à partir de MSDN, ou vous pouvez le créer vous-même.You can download the code that this topic uses from MSDN, or you can build it yourself.

Notes

Pour exécuter l’exemple, vous devez disposer de Visual Studio 2012 ou version ultérieure et du .NET Framework 4,5 ou plus récent installé sur votre ordinateur.To run the example, you must have Visual Studio 2012 or newer and the .NET Framework 4.5 or newer installed on your computer.

Télécharger le programmeDownload the Program

L’application utilisée dans cette rubrique est téléchargeable dans Async Sample: Control Flow in Async Programs (Exemple Async : Flux de contrôle dans les programmes Async).You can download the application for this topic from Async Sample: Control Flow in Async Programs. Les étapes suivantes ouvrent et exécutent le programme.The following steps open and run the program.

  1. Décompressez le fichier téléchargé, puis démarrez Visual Studio.Unzip the downloaded file, and then start Visual Studio.

  2. Dans la barre de menus, choisissez Fichier, Ouvrir, Projet/Solution.On the menu bar, choose File, Open, Project/Solution.

  3. Accédez au dossier qui contient l’exemple de code décompressé, ouvrez le fichier solution (.sln), puis choisissez la touche F5 pour générer et exécuter le projet.Navigate to the folder that holds the unzipped sample code, open the solution (.sln) file, and then choose the F5 key to build and run the project.

Générer le programme vous-mêmeBuild the Program Yourself

Le projet Windows Presentation Foundation (WPF) suivant contient l’exemple de code utilisé pour cette rubrique.The following Windows Presentation Foundation (WPF) project contains the code example for this topic.

Pour exécuter le projet, procédez comme suit :To run the project, perform the following steps:

  1. Démarrez Visual Studio.Start Visual Studio.

  2. Dans la barre de menus, sélectionnez Fichier, Nouveau, Projet.On the menu bar, choose File, New, Project.

    La boîte de dialogue Nouveau projet s'affiche.The New Project dialog box opens.

  3. Dans le volet modèles installés , choisissez Visual Basic, puis choisissez application WPF dans la liste des types de projets.In the Installed Templates pane, choose Visual Basic, and then choose WPF Application from the list of project types.

  4. Entrez AsyncTracer comme nom du projet, puis choisissez le bouton OK.Enter AsyncTracer as the name of the project, and then choose the OK button.

    Le nouveau projet s’affiche dans l’Explorateur de solutions.The new project appears in Solution Explorer.

  5. Dans l'éditeur de code Visual Studio, choisissez l'onglet MainWindow.xaml .In the Visual Studio Code Editor, choose the MainWindow.xaml tab.

    Si l’onglet n’est pas visible, ouvrez le menu contextuel de MainWindow.xaml dans l’Explorateur de solutions, puis choisissez Afficher le code.If the tab isn’t visible, open the shortcut menu for MainWindow.xaml in Solution Explorer, and then choose View Code.

  6. Dans la vue XAML de MainWindow.xaml, remplacez le code par le code suivant.In the XAML view of MainWindow.xaml, replace the code with the following code.

    <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow"
        Title="Control Flow Trace" Height="350" Width="525">
        <Grid>
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="221,10,0,0" VerticalAlignment="Top" Width="75"/>
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Bottom" Width="510" Height="265" FontFamily="Lucida Console" FontSize="10" VerticalScrollBarVisibility="Visible" d:LayoutOverrides="HorizontalMargin"/>
    
        </Grid>
    </Window>
    

    Une fenêtre simple contenant une zone de texte et un bouton apparaît dans la vue Design de MainWindow.xaml.A simple window that contains a text box and a button appears in the Design view of MainWindow.xaml.

  7. Ajoutez une référence pour System.Net.Http.Add a reference for System.Net.Http.

  8. Dans Explorateur de solutions, ouvrez le menu contextuel de MainWindow. Xaml. vb, puis choisissez afficher le code.In Solution Explorer, open the shortcut menu for MainWindow.xaml.vb, and then choose View Code.

  9. Dans MainWindow. Xaml. vb, remplacez le code par le code suivant.In MainWindow.xaml.vb , replace the code with the following code.

    ' Add an Imports statement and a reference for System.Net.Http.
    Imports System.Net.Http
    
    Class MainWindow
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click
    
            ' The display lines in the example lead you through the control shifts.
            ResultsTextBox.Text &= "ONE:   Entering StartButton_Click." & vbCrLf &
                "           Calling AccessTheWebAsync." & vbCrLf
    
            Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
    
            ResultsTextBox.Text &= vbCrLf & "FOUR:  Back in StartButton_Click." & vbCrLf &
                "           Task getLengthTask is started." & vbCrLf &
                "           About to await getLengthTask -- no caller to return to." & vbCrLf
    
            Dim contentLength As Integer = Await getLengthTask
    
            ResultsTextBox.Text &= vbCrLf & "SIX:   Back in StartButton_Click." & vbCrLf &
                "           Task getLengthTask is finished." & vbCrLf &
                "           Result from AccessTheWebAsync is stored in contentLength." & vbCrLf &
                "           About to display contentLength and exit." & vbCrLf
    
            ResultsTextBox.Text &=
                String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
        End Sub
    
        Async Function AccessTheWebAsync() As Task(Of Integer)
    
            ResultsTextBox.Text &= vbCrLf & "TWO:   Entering AccessTheWebAsync."
    
            ' Declare an HttpClient object.
            Dim client As HttpClient = New HttpClient()
    
            ResultsTextBox.Text &= vbCrLf & "           Calling HttpClient.GetStringAsync." & vbCrLf
    
            ' GetStringAsync returns a Task(Of String).
            Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")
    
            ResultsTextBox.Text &= vbCrLf & "THREE: Back in AccessTheWebAsync." & vbCrLf &
                "           Task getStringTask is started."
    
            ' AccessTheWebAsync can continue to work until getStringTask is awaited.
    
            ResultsTextBox.Text &=
                vbCrLf & "           About to await getStringTask & return a Task(Of Integer) to StartButton_Click." & vbCrLf
    
            ' Retrieve the website contents when task is complete.
            Dim urlContents As String = Await getStringTask
    
            ResultsTextBox.Text &= vbCrLf & "FIVE:  Back in AccessTheWebAsync." &
                vbCrLf & "           Task getStringTask is complete." &
                vbCrLf & "           Processing the return statement." &
                vbCrLf & "           Exiting from AccessTheWebAsync." & vbCrLf
    
            Return urlContents.Length
        End Function
    
    End Class
    
  10. Appuyez sur la touche F5 pour exécuter le programme, puis choisissez le bouton Démarrer .Choose the F5 key to run the program, and then choose the Start button.

    La sortie suivante doit s’afficher :The following output should appear:

    ONE:   Entering startButton_Click.
               Calling AccessTheWebAsync.
    
    TWO:   Entering AccessTheWebAsync.
               Calling HttpClient.GetStringAsync.
    
    THREE: Back in AccessTheWebAsync.
               Task getStringTask is started.
               About to await getStringTask & return a Task<int> to startButton_Click.
    
    FOUR:  Back in startButton_Click.
               Task getLengthTask is started.
               About to await getLengthTask -- no caller to return to.
    
    FIVE:  Back in AccessTheWebAsync.
               Task getStringTask is complete.
               Processing the return statement.
               Exiting from AccessTheWebAsync.
    
    SIX:   Back in startButton_Click.
               Task getLengthTask is finished.
               Result from AccessTheWebAsync is stored in contentLength.
               About to display contentLength and exit.
    
    Length of the downloaded string: 33946.
    

Tracer le programmeTrace the Program

Étapes UN et DEUXSteps ONE and TWO

Les deux premières lignes d’affichage suivent le chemin quand startButton_Click appelle AccessTheWebAsync et AccessTheWebAsync appelle la méthode asynchrone HttpClient GetStringAsync(String).The first two display lines trace the path as startButton_Click calls AccessTheWebAsync, and AccessTheWebAsync calls the asynchronous HttpClient method GetStringAsync(String). L’image suivante montre les appels de méthode à méthode.The following image outlines the calls from method to method.

Étapes ONE et TWOSteps ONE and TWO

Le type de retour de AccessTheWebAsync et de client.GetStringAsync est Task<TResult>.The return type of both AccessTheWebAsync and client.GetStringAsync is Task<TResult>. Pour AccessTheWebAsync, TResult est un entier.For AccessTheWebAsync, TResult is an integer. Pour GetStringAsync, TResult est une chaîne.For GetStringAsync, TResult is a string. Pour plus d’informations sur les types de retour de méthode Async, consultez types de retour Async (Visual Basic).For more information about async method return types, see Async Return Types (Visual Basic).

Une méthode async retournant une tâche retourne une instance de tâche quand le contrôle revient vers l’appelant.A task-returning async method returns a task instance when control shifts back to the caller. Le contrôle retourne d’une méthode async à son appelant quand un opérateur Await est rencontré dans la méthode appelée ou quand la méthode appelée se termine.Control returns from an async method to its caller either when an Await operator is encountered in the called method or when the called method ends. Les lignes qui sont étiquetées "THREE" à "SIX" suivent cette partie du processus.The display lines that are labeled "THREE" through "SIX" trace this part of the process.

Étape TROISStep THREE

Dans AccessTheWebAsync, la méthode asynchrone GetStringAsync(String) est appelée pour télécharger le contenu de la page web cible.In AccessTheWebAsync, the asynchronous method GetStringAsync(String) is called to download the contents of the target webpage. Le contrôle retourne de client.GetStringAsync à AccessTheWebAsync quand client.GetStringAsync retourne une sortie.Control returns from client.GetStringAsync to AccessTheWebAsync when client.GetStringAsync returns.

La méthode client.GetStringAsync retourne une tâche de la chaîne assignée à la variable getStringTask dans AccessTheWebAsync.The client.GetStringAsync method returns a task of string that’s assigned to the getStringTask variable in AccessTheWebAsync. La ligne suivante de l’exemple de programme illustre l’appel à client.GetStringAsync et l’assignation.The following line in the example program shows the call to client.GetStringAsync and the assignment.

Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")

Vous pouvez considérer la tâche comme une promesse faite par client.GetStringAsync de produire au final une chaîne réelle.You can think of the task as a promise by client.GetStringAsync to produce an actual string eventually. Pour le moment, si AccessTheWebAsync a du travail à effectuer qui ne dépend pas de la chaîne promise de client.GetStringAsync, ce travail peut se poursuivre pendant que client.GetStringAsync attend.In the meantime, if AccessTheWebAsync has work to do that doesn't depend on the promised string from client.GetStringAsync, that work can continue while client.GetStringAsync waits. Dans l’exemple, les lignes de sortie suivantes, qui sont étiquetées « THREE », représentent la possibilité d’effectuer un travail indépendantIn the example, the following lines of output, which are labeled "THREE," represent the opportunity to do independent work

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

L’instruction suivante interrompt la progression dans AccessTheWebAsync quand getStringTask est attendu.The following statement suspends progress in AccessTheWebAsync when getStringTask is awaited.

Dim urlContents As String = Await getStringTask

L’illustration suivante montre le déroulement du contrôle de client.GetStringAsync à l’assignation à getStringTask et de la création de getStringTask à l’application d’un opérateur await.The following image shows the flow of control from client.GetStringAsync to the assignment to getStringTask and from the creation of getStringTask to the application of an Await operator.

Étape THREEStep THREE

L’expression await suspend AccessTheWebAsync jusqu’à ce que client.GetStringAsync retourne une sortie.The await expression suspends AccessTheWebAsync until client.GetStringAsync returns. Dans le même temps, le contrôle retourne à l’appelant de AccessTheWebAsync, startButton_Click.In the meantime, control returns to the caller of AccessTheWebAsync, startButton_Click.

Notes

En général, vous attendez immédiatement l’appel à une méthode asynchrone.Typically, you await the call to an asynchronous method immediately. Par exemple, l’assignation suivante peut substituer le code précédent qui crée, puis attend getStringTask : Dim urlContents As String = Await client.GetStringAsync("https://msdn.microsoft.com")For example, the following assignment could replace the previous code that creates and then awaits getStringTask: Dim urlContents As String = Await client.GetStringAsync("https://msdn.microsoft.com")

Dans cette rubrique, l’opérateur await est appliqué ultérieurement pour s’adapter aux lignes de sortie qui marquent le flux de contrôle dans le programme.In this topic, the await operator is applied later to accommodate the output lines that mark the flow of control through the program.

Étape FOURStep FOUR

Le type de retour déclaré de AccessTheWebAsync est Task(Of Integer).The declared return type of AccessTheWebAsync is Task(Of Integer). Par conséquent, quand la méthode AccessTheWebAsync est suspendue, elle retourne une tâche d’entier à startButton_Click.Therefore, when AccessTheWebAsync is suspended, it returns a task of integer to startButton_Click. Vous devez comprendre que la tâche retournée n’est pas getStringTask.You should understand that the returned task isn’t getStringTask. Il s’agit d’une tâche d’entier qui représente ce qu’il reste à effectuer dans la méthode interrompue, AccessTheWebAsync.The returned task is a new task of integer that represents what remains to be done in the suspended method, AccessTheWebAsync. La tâche est une promesse de AccessTheWebAsync de produire un entier quand la tâche est terminée.The task is a promise from AccessTheWebAsync to produce an integer when the task is complete.

L’instruction suivante assigne cette tâche à la variable getLengthTask.The following statement assigns this task to the getLengthTask variable.

Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()

Comme dans AccessTheWebAsync, startButton_Click peut continuer le travail qui ne dépend pas des résultats de la tâche asynchrone (getLengthTask) jusqu’à ce que la tâche soit attendue.As in AccessTheWebAsync, startButton_Click can continue with work that doesn’t depend on the results of the asynchronous task (getLengthTask) until the task is awaited. Les lignes de sortie suivantes représentent ce travail :The following output lines represent that work:

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.

La progression dans startButton_Click est suspendue quand getLengthTask est attendu.Progress in startButton_Click is suspended when getLengthTask is awaited. L’instruction d’assignation suivante interrompt startButton_Click jusqu’à ce que la méthode AccessTheWebAsync soit terminée.The following assignment statement suspends startButton_Click until AccessTheWebAsync is complete.

Dim contentLength As Integer = Await getLengthTask

Dans l’illustration suivante, les flèches indiquent le flux de contrôle entre l’expression await dans AccessTheWebAsync et l’assignation d’une valeur à getLengthTask, suivie du traitement normal dans startButton_Click jusqu’à ce que getLengthTask soit attendu.In the following illustration, the arrows show the flow of control from the await expression in AccessTheWebAsync to the assignment of a value to getLengthTask, followed by normal processing in startButton_Click until getLengthTask is awaited.

Étape FOURStep FOUR

Étape FIVEStep FIVE

Quand client.GetStringAsync signale que son exécution est terminée, le traitement dans AccessTheWebAsync est libéré de la suspension et peut continuer après l’instruction await.When client.GetStringAsync signals that it’s complete, processing in AccessTheWebAsync is released from suspension and can continue past the await statement. Les lignes de sortie suivantes représentent la reprise du traitement :The following lines of output represent the resumption of processing:

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

L’opérande de l’instruction return, urlContents.Length, est stocké dans la tâche que AccessTheWebAsync retourne.The operand of the return statement, urlContents.Length, is stored in the task that AccessTheWebAsync returns. L’expression await récupère cette valeur à partir de getLengthTask dans startButton_Click.The await expression retrieves that value from getLengthTask in startButton_Click.

L’illustration suivante présente le transfert du contrôle après l’exécution de client.GetStringAsync (et de getStringTask).The following image shows the transfer of control after client.GetStringAsync (and getStringTask) are complete.

Étape FIVEStep FIVE

AccessTheWebAsync s’exécute jusqu’à la fin et le contrôle retourne à startButton_Click, qui attend que son exécution soit terminée.AccessTheWebAsync runs to completion, and control returns to startButton_Click, which is awaiting the completion.

Étape SIXStep SIX

Quand AccessTheWebAsync signale que son exécution est terminée, le traitement peut continuer après l’instruction await dans startButton_Async.When AccessTheWebAsync signals that it’s complete, processing can continue past the await statement in startButton_Async. En fait, le programme n’a plus rien d’autre à faire.In fact, the program has nothing more to do.

Les lignes de sortie suivantes représentent la reprise du traitement dans startButton_Async :The following lines of output represent the resumption of processing in startButton_Async:

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

L’expression await récupère de getLengthTask la valeur entière qui est l’opérande de l’instruction return dans AccessTheWebAsync.The await expression retrieves from getLengthTask the integer value that’s the operand of the return statement in AccessTheWebAsync. L’instruction suivante assigne cette valeur à la variable contentLength.The following statement assigns that value to the contentLength variable.

Dim contentLength As Integer = Await getLengthTask

L’illustration suivante montre le retour du contrôle de AccessTheWebAsync à startButton_Click.The following image shows the return of control from AccessTheWebAsync to startButton_Click.

Étape SIXStep SIX

Voir aussiSee also