Démarrer plusieurs tâches Asynch et les traiter une fois terminées (Visual Basic)Start Multiple Async Tasks and Process Them As They Complete (Visual Basic)

En utilisant Task.WhenAny, vous pouvez démarrer plusieurs tâches en même temps et les traiter une par une, une fois qu’elles sont terminées, au lieu de les traiter dans l’ordre dans lequel elles ont démarré.By using Task.WhenAny, you can start multiple tasks at the same time and process them one by one as they’re completed rather than process them in the order in which they're started.

L’exemple suivant utilise une requête pour créer une collection de tâches.The following example uses a query to create a collection of tasks. Chaque tâche télécharge le contenu d’un site web spécifié.Each task downloads the contents of a specified website. À chaque itération d’une boucle while, un appel attendu à WhenAny retourne la tâche de la collection de tâches dont le téléchargement se termine en premier.In each iteration of a while loop, an awaited call to WhenAny returns the task in the collection of tasks that finishes its download first. Cette tâche est supprimée de la collection et traitée.That task is removed from the collection and processed. La boucle se répète jusqu’à ce que la collection ne contienne plus aucune tâche.The loop repeats until the collection contains no more tasks.

Notes

Pour exécuter les exemples, Visual Studio 2012 ou version ultérieure et .NET Framework 4.5 ou version ultérieure doivent être installés sur votre ordinateur.To run the examples, you must have Visual Studio 2012 or newer and the .NET Framework 4.5 or newer installed on your computer.

Téléchargement de l'exempleDownloading the Example

Téléchargez l’intégralité du projet Windows Presentation Foundation (WPF) à partir de la page Exemple Async : réglage de votre application, puis procédez comme suit.You can download the complete Windows Presentation Foundation (WPF) project from Async Sample: Fine Tuning Your Application and then follow these steps.

  1. Décompressez le fichier que vous avez téléchargé, puis démarrez Visual Studio.Decompress the file that you downloaded, 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. Dans la boîte de dialogue Ouvrir le projet, ouvrez le dossier contenant l’exemple de code que vous avez décompressé, puis ouvrez le fichier de solution (.sln) pour AsyncFineTuningVB.In the Open Project dialog box, open the folder that holds the sample code that you decompressed, and then open the solution (.sln) file for AsyncFineTuningVB.

  4. Dans l’Explorateur de solutions, ouvrez le menu contextuel pour le projet ProcessTasksAsTheyFinish, puis choisissez Définir comme projet de démarrage.In Solution Explorer, open the shortcut menu for the ProcessTasksAsTheyFinish project, and then choose Set as StartUp Project.

  5. Appuyez sur la touche F5 pour exécuter le projet.Choose the F5 key to run the project.

    Appuyez sur les touches Ctrl+F5 pour exécuter le projet sans le déboguer.Choose the Ctrl+F5 keys to run the project without debugging it.

  6. Exécutez le projet plusieurs fois pour vérifier que les longueurs téléchargées n’apparaissent pas toujours dans le même ordre.Run the project several times to verify that the downloaded lengths don't always appear in the same order.

Si vous ne souhaitez pas télécharger le projet, vous pouvez passer en revue le fichier MainWindow.xaml.vb à la fin de cette rubrique.If you don't want to download the project, you can review the MainWindow.xaml.vb file at the end of this topic.

Génération de l’exempleBuilding the Example

Cet exemple ajoute au code développé dans annuler les tâches asynchrones restantes après l’achèvement de l’opération (Visual Basic) et utilise la même interface utilisateur.This example adds to the code that’s developed in Cancel Remaining Async Tasks after One Is Complete (Visual Basic) and uses the same UI.

Pour générer l’exemple vous-même, pas à pas, suivez les instructions de la section « Téléchargement de l’exemple », mais choisissez CancelAfterOneTask comme Projet de démarrage.To build the example yourself, step by step, follow the instructions in the "Downloading the Example" section, but choose CancelAfterOneTask as the StartUp Project. Ajoutez les modifications de cette rubrique à la méthode AccessTheWebAsync dans ce projet.Add the changes in this topic to the AccessTheWebAsync method in that project. Les modifications sont marquées par des astérisques.The changes are marked with asterisks.

Le projet CancelAfterOneTask inclut déjà une requête qui, lorsqu’elle est exécutée, crée une collection de tâches.The CancelAfterOneTask project already includes a query that, when executed, creates a collection of tasks. Chaque appel à ProcessURLAsync dans le code suivant retourne un Task<TResult>TResult est un entier.Each call to ProcessURLAsync in the following code returns a Task<TResult> where TResult is an integer.

Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =  
    From url In urlList Select ProcessURLAsync(url, client, ct)  

Dans le fichier MainWindow. Xaml. vb du projet, apportez les modifications suivantes à la AccessTheWebAsync méthode.In the MainWindow.xaml.vb file of the project, make the following changes to the AccessTheWebAsync method.

  • Exécutez la requête en appliquant Enumerable.ToList au lieu de ToArray.Execute the query by applying Enumerable.ToList instead of ToArray.

    Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()  
    
  • Ajoutez une boucle while qui effectue les étapes suivantes pour chaque tâche dans la collection.Add a while loop that performs the following steps for each task in the collection.

    1. Elle attend un appel à WhenAny pour identifier la première tâche dans la collection afin de terminer son téléchargement.Awaits a call to WhenAny to identify the first task in the collection to finish its download.

      Dim firstFinishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)  
      
    2. Elle supprime cette tâche de la collection.Removes that task from the collection.

      downloadTasks.Remove(firstFinishedTask)  
      
    3. Elle attend firstFinishedTask, qui est retourné par un appel à ProcessURLAsync.Awaits firstFinishedTask, which is returned by a call to ProcessURLAsync. La variable firstFinishedTask est un Task<TResult>TReturn est un entier.The firstFinishedTask variable is a Task<TResult> where TReturn is an integer. La tâche est déjà terminée, mais vous l’attendez pour récupérer la longueur du site web téléchargé, comme le montre l’exemple suivant.The task is already complete, but you await it to retrieve the length of the downloaded website, as the following example shows.

      Dim length = Await firstFinishedTask  
      resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website:  {0}" & vbCrLf, length)  
      

Vous devez exécuter le projet plusieurs fois pour vérifier que les longueurs téléchargées n’apparaissent pas toujours dans le même ordre.You should run the project several times to verify that the downloaded lengths don't always appear in the same order.

Attention

Vous pouvez utiliser WhenAny dans une boucle, comme décrit dans l’exemple, pour résoudre les problèmes qui impliquent un petit nombre de tâches.You can use WhenAny in a loop, as described in the example, to solve problems that involve a small number of tasks. Cependant, d’autres approches sont plus efficaces si vous avez un grand nombre de tâches à traiter.However, other approaches are more efficient if you have a large number of tasks to process. Pour plus d’informations et d’exemples, consultez l’article relatif au traitement des tâches une fois terminées.For more information and examples, see Processing Tasks as they complete.

Exemple completComplete Example

Le code suivant est le texte complet du fichier MainWindow.xaml.vb de l’exemple.The following code is the complete text of the MainWindow.xaml.vb file for the example. Des astérisques marquent les éléments ajoutés pour cet exemple.Asterisks mark the elements that were added for this example.

Notez que vous devez ajouter une référence pour System.Net.Http.Notice that you must add a reference for System.Net.Http.

Vous pouvez télécharger le projet à partir de la page Exemple Async : réglage de votre application.You can download the project from Async Sample: Fine Tuning Your Application.

' Add an Imports directive and a reference for System.Net.Http.  
Imports System.Net.Http  
  
' Add the following Imports directive for System.Threading.  
Imports System.Threading  
  
Class MainWindow  
  
    ' Declare a System.Threading.CancellationTokenSource.  
    Dim cts As CancellationTokenSource  
  
    Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)  
  
        ' Instantiate the CancellationTokenSource.  
        cts = New CancellationTokenSource()  
  
        resultsTextBox.Clear()  
  
        Try  
            Await AccessTheWebAsync(cts.Token)  
            resultsTextBox.Text &= vbCrLf & "Downloads complete."  
  
        Catch ex As OperationCanceledException  
            resultsTextBox.Text &= vbCrLf & "Downloads canceled." & vbCrLf  
  
        Catch ex As Exception  
            resultsTextBox.Text &= vbCrLf & "Downloads failed." & vbCrLf  
        End Try  
  
        ' Set the CancellationTokenSource to Nothing when the download is complete.  
        cts = Nothing  
    End Sub  
  
    ' You can still include a Cancel button if you want to.  
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)  
  
        If cts IsNot Nothing Then  
            cts.Cancel()  
        End If  
    End Sub  
  
    ' Provide a parameter for the CancellationToken.  
    ' Change the return type to Task because the method has no return statement.  
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task  
  
        Dim client As HttpClient = New HttpClient()  
  
        ' Call SetUpURLList to make a list of web addresses.  
        Dim urlList As List(Of String) = SetUpURLList()  
  
        ' ***Create a query that, when executed, returns a collection of tasks.  
        Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =  
            From url In urlList Select ProcessURLAsync(url, client, ct)  
  
        ' ***Use ToList to execute the query and start the download tasks.
        Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()  
  
        ' ***Add a loop to process the tasks one at a time until none remain.  
        While downloadTasks.Count > 0  
            ' ***Identify the first task that completes.  
            Dim firstFinishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)  
  
            ' ***Remove the selected task from the list so that you don't  
            ' process it more than once.  
            downloadTasks.Remove(firstFinishedTask)  
  
            ' ***Await the first completed task and display the results.  
            Dim length = Await firstFinishedTask  
            resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website:  {0}" & vbCrLf, length)  
        End While  
  
    End Function  
  
    ' Bundle the processing steps for a website into one async method.  
    Async Function ProcessURLAsync(url As String, client As HttpClient, ct As CancellationToken) As Task(Of Integer)  
  
        ' GetAsync returns a Task(Of HttpResponseMessage).
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)  
  
        ' Retrieve the website contents from the HttpResponseMessage.  
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()  
  
        Return urlContents.Length  
    End Function  
  
    ' Add a method that creates a list of web addresses.  
    Private Function SetUpURLList() As List(Of String)  
  
        Dim urls = New List(Of String) From  
            {  
                "https://msdn.microsoft.com",  
                "https://msdn.microsoft.com/library/hh290138.aspx",  
                "https://msdn.microsoft.com/library/hh290140.aspx",  
                "https://msdn.microsoft.com/library/dd470362.aspx",  
                "https://msdn.microsoft.com/library/aa578028.aspx",  
                "https://msdn.microsoft.com/library/ms404677.aspx",  
                "https://msdn.microsoft.com/library/ff730837.aspx"  
            }  
        Return urls  
    End Function  
  
End Class  
  
' Sample output:  
  
' Length of the download:  226093  
' Length of the download:  412588  
' Length of the download:  175490  
' Length of the download:  204890  
' Length of the download:  158855  
' Length of the download:  145790  
' Length of the download:  44908  
' Downloads complete.  

Voir aussiSee also