Comment : effectuer plusieurs requêtes Web en parallèle (C# et Visual Basic)

Dans une méthode async, les tâches sont démarrées lorsqu'elles sont créées.L'opérateur d' attendez (Visual Basic) ou d' attendez (C#) est appliqué à la tâche déboguer dans la méthode où le traitement ne peut pas continuer jusqu'à ce que la tâche se termine.Souvent une tâche est attendue dès qu'elle crée, comme indiqué dans l'exemple suivant.

Dim result = Await someWebAccessMethodAsync(url)
var result = await someWebAccessMethodAsync(url);

Toutefois, vous pouvez séparer créer la tâche d'attendre la tâche si votre programme a un autre travail à accomplir qui ne dépend pas de l'achèvement de la tâche.

' The following line creates and starts the task.
Dim myTask = someWebAccessMethodAsync(url)

' While the task is running, you can do other work that does not depend
' on the results of the task.
' . . . . .

' The application of Await suspends the rest of this method until the task is 
' complete.
Dim result = Await myTask
// The following line creates and starts the task.
var myTask = someWebAccessMethodAsync(url);

// While the task is running, you can do other work that doesn't depend
// on the results of the task.
// . . . . .

// The application of await suspends the rest of this method until the task is complete.
var result = await myTask;

Entre lancer une tâche et l'attendre, vous pouvez démarrer d'autres tâches.Les tâches supplémentaires fonctionnent implicitement en parallèle, mais aucun thread supplémentaire n'est créé.

Le programme démarre suivants trois téléchargements asynchrones de site Web et attend ensuite dans l'ordre dans lequel elles sont appelées.Notez, lorsque vous exécutez le programme, que les tâches ne se terminent pas toujours dans l'ordre dans lequel elles sont créées et attendues.Il commence à s'exécuter lorsqu'elles sont créées, et un ou plusieurs des tâches peuvent se termine avant que la méthode atteigne les expressions d'attente.

Pour obtenir un autre exemple qui commence plusieurs tâches en même temps, consultez Comment : étendre la procédure pas à pas à l'aide de Task.WhenAll (C# et Visual Basic).

Pour exécuter ce projet, vous devez avoir Visual Studio 2012 installé sur votre ordinateur.Pour plus d'informations, consultez le site Web Microsoft.

Vous pouvez télécharger le code de cet exemple de Exemples de code de développement.

Pour configurer le projet

  • Pour installer une application WPF, exécutez les étapes suivantes.Vous pouvez rechercher le obtenir des instructions détaillées pour ces étapes dans Procédure pas à pas : accès au Web avec Async et Await (C# et Visual Basic).

    • Créer une application WPF qui contient une zone de texte et un bouton.Nommez le bouton startButton, puis nommez la zone de texte resultsTextBox.

    • Ajoutez une référence pour System.Net.Http.

    • Dans MainWindow.xaml.vb ou MainWindow.xaml.cs, ajoutez une instruction d' Imports ou une directive d' using pour System.Net.Http.

Pour ajouter du code

  1. Dans la fenêtre de conception, MainWindow.xaml, double-cliquez sur le bouton pour créer le gestionnaire d'événements d' startButton_Click dans MainWindow.xaml.vb ou MainWindow.xaml.cs.Comme alternative, sélectionnez le bouton, sélectionnez l'icône Gestionnaires d'événements pour les éléments sélectionnés dans la fenêtre Propriétés , puis entrez startButton_Click dans la zone de texte Clic .

  2. Copiez le code suivant, puis collez -le dans le corps d' startButton_Click dans MainWindow.xaml.vb ou MainWindow.xaml.cs.

    resultsTextBox.Clear()
    Await CreateMultipleTasksAsync()
    resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    
    resultsTextBox.Clear();
    await CreateMultipleTasksAsync();
    resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
    

    Le code appelle une méthode asynchrone, CreateMultipleTasksAsync, qui pilote l'application.

  3. Ajoutez les méthodes suivantes de prise en charge au projet :

    • ProcessURLAsync utilise une méthode d' HttpClient pour télécharger le contenu d'un site Web comme un tableau d'octets.La méthode de charge, ProcessURLAsync ensuite affiche et retourne la longueur du tableau.

    • DisplayResults affiche le nombre d'octets dans le tableau d'octets pour chaque URL.Cet affichage affiche lorsque chaque tâche est terminée télécharger.

    Copiez les méthodes suivantes, puis collez -les après le gestionnaire d'événements d' startButton_Click dans MainWindow.xaml.vb ou MainWindow.xaml.cs.

    Private Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer)
    
        Dim byteArray = Await client.GetByteArrayAsync(url)
        DisplayResults(url, byteArray)
        Return byteArray.Length
    End Function
    
    
    Private Sub DisplayResults(url As String, content As Byte())
    
        ' Display the length of each website. The string format 
        ' is designed to be used with a monospaced font, such as
        ' Lucida Console or Global Monospace.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
    
    async Task<int> ProcessURLAsync(string url, HttpClient client)
    {
        var byteArray = await client.GetByteArrayAsync(url);
        DisplayResults(url, byteArray);
        return byteArray.Length;
    }
    
    
    private void DisplayResults(string url, byte[] content)
    {
        // Display the length of each website. The string format 
        // is designed to be used with a monospaced font, such as
        // Lucida Console or Global Monospace.
        var bytes = content.Length;
        // Strip off the "http://".
        var displayURL = url.Replace("http://", "");
        resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
    }
    
  4. Enfin, définissez la méthode CreateMultipleTasksAsync, qui effectue les étapes suivantes.

    • La méthode déclare un objet d' HttpClient , dont vous avez besoin de la méthode d'accès GetByteArrayAsync dans ProcessURLAsync.

    • La méthode crée et démarre trois tâches de type Task<TResult>, où TResult est un entier.Chaque fois qu'une tâche se termine, DisplayResults affiche l'URL et la longueur de la tâche du contenu téléchargé.Étant donné que les tâches s'exécutent de manière asynchrone, l'ordre dans lequel les résultats s'affichent peuvent être différentes de l'ordre dans lequel il a été déclaré.

    • La méthode attend la fin de chaque tâche.Chaque opérateur d' Await ou d' await interrompt l'exécution d' CreateMultipleTasksAsync jusqu'à ce que la tâche attendue terminée.l'opérateur extrait également la valeur de retour de l'appel à ProcessURLAsync de chaque tâche achevée.

    • Lorsque les tâches ont été exécutées et les valeurs entières ont été récupérées, la méthode ajoute les longueurs des sites Web et affiche le résultat.

    Copiez la méthode suivante, et collez-la dans votre solution.

    Private Async Function CreateMultipleTasksAsync() As Task
    
        ' Declare an HttpClient object, and increase the buffer size. The
        ' default buffer size is 65,536.
        Dim client As HttpClient =
            New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
    
        ' Create and start the tasks. As each task finishes, DisplayResults 
        ' displays its length.
        Dim download1 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com", client)
        Dim download2 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client)
    
        ' Await each task.
        Dim length1 As Integer = Await download1
        Dim length2 As Integer = Await download2
        Dim length3 As Integer = Await download3
    
        Dim total As Integer = length1 + length2 + length3
    
        ' Display the total count for all of the websites.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
                                             "Total bytes returned:  {0}" & vbCrLf, total)
    End Function
    
    private async Task CreateMultipleTasksAsync()
    {
        // Declare an HttpClient object, and increase the buffer size. The
        // default buffer size is 65,536.
        HttpClient client =
            new HttpClient() { MaxResponseContentBufferSize = 1000000 };
    
        // Create and start the tasks. As each task finishes, DisplayResults 
        // displays its length.
        Task<int> download1 = 
            ProcessURLAsync("https://msdn.microsoft.com", client);
        Task<int> download2 = 
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
        Task<int> download3 = 
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);
    
        // Await each task.
        int length1 = await download1;
        int length2 = await download2;
        int length3 = await download3;
    
        int total = length1 + length2 + length3;
    
        // Display the total count for the downloaded websites.
        resultsTextBox.Text +=
            string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
    }
    
  5. Choisissez la touche F5 pour exécuter le programme, puis choisissez le bouton Démarrer .

    Exécutez le programme plusieurs fois pour vérifier que les trois tâches ne se terminent pas toujours dans le même ordre et que l'ordre dans lequel elles se terminent n'est pas nécessairement l'ordre dans lequel ils sont créés et attendus.

Exemple

Le code suivant inclut l'exemple complet.

' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http


Class MainWindow

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
        resultsTextBox.Clear()
        Await CreateMultipleTasksAsync()
        resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    End Sub


    Private Async Function CreateMultipleTasksAsync() As Task

        ' Declare an HttpClient object, and increase the buffer size. The
        ' default buffer size is 65,536.
        Dim client As HttpClient =
            New HttpClient() With {.MaxResponseContentBufferSize = 1000000}

        ' Create and start the tasks. As each task finishes, DisplayResults 
        ' displays its length.
        Dim download1 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com", client)
        Dim download2 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client)

        ' Await each task.
        Dim length1 As Integer = Await download1
        Dim length2 As Integer = Await download2
        Dim length3 As Integer = Await download3

        Dim total As Integer = length1 + length2 + length3

        ' Display the total count for all of the websites.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
                                             "Total bytes returned:  {0}" & vbCrLf, total)
    End Function


    Private Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer)

        Dim byteArray = Await client.GetByteArrayAsync(url)
        DisplayResults(url, byteArray)
        Return byteArray.Length
    End Function


    Private Sub DisplayResults(url As String, content As Byte())

        ' Display the length of each website. The string format 
        ' is designed to be used with a monospaced font, such as
        ' Lucida Console or Global Monospace.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directive, and add a reference for System.Net.Http.
using System.Net.Http;


namespace AsyncExample_MultipleTasks
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            resultsTextBox.Clear();
            await CreateMultipleTasksAsync();
            resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
        }


        private async Task CreateMultipleTasksAsync()
        {
            // Declare an HttpClient object, and increase the buffer size. The
            // default buffer size is 65,536.
            HttpClient client =
                new HttpClient() { MaxResponseContentBufferSize = 1000000 };

            // Create and start the tasks. As each task finishes, DisplayResults 
            // displays its length.
            Task<int> download1 = 
                ProcessURLAsync("https://msdn.microsoft.com", client);
            Task<int> download2 = 
                ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
            Task<int> download3 = 
                ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);

            // Await each task.
            int length1 = await download1;
            int length2 = await download2;
            int length3 = await download3;

            int total = length1 + length2 + length3;

            // Display the total count for the downloaded websites.
            resultsTextBox.Text +=
                string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
        }


        async Task<int> ProcessURLAsync(string url, HttpClient client)
        {
            var byteArray = await client.GetByteArrayAsync(url);
            DisplayResults(url, byteArray);
            return byteArray.Length;
        }


        private void DisplayResults(string url, byte[] content)
        {
            // Display the length of each website. The string format 
            // is designed to be used with a monospaced font, such as
            // Lucida Console or Global Monospace.
            var bytes = content.Length;
            // Strip off the "http://".
            var displayURL = url.Replace("http://", "");
            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
        }
    }
}

Voir aussi

Tâches

Procédure pas à pas : accès au Web avec Async et Await (C# et Visual Basic)

Comment : étendre la procédure pas à pas à l'aide de Task.WhenAll (C# et Visual Basic)

Concepts

Programmation asynchrone avec Async et Await (C# et Visual Basic)