Delen via


Procedure: Meerdere webaanvragen parallel maken met behulp van Async en Await (Visual Basic)

In een asynchrone methode worden taken gestart wanneer ze worden gemaakt. De operator Await wordt toegepast op de taak op het punt in de methode waar de verwerking pas kan worden voortgezet als de taak is voltooid. Vaak wordt er op een taak gewacht zodra deze is gemaakt, zoals in het volgende voorbeeld wordt weergegeven.

Dim result = Await someWebAccessMethodAsync(url)

U kunt het maken van de taak echter scheiden van wachten op de taak als uw programma ander werk heeft dat niet afhankelijk is van de voltooiing van de taak.

' 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

Tussen het starten van een taak en het wachten hierop, kunt u andere taken starten. De extra taken worden impliciet parallel uitgevoerd, maar er worden geen extra threads gemaakt.

Het volgende programma start drie asynchrone webdownloads en wacht vervolgens in de volgorde waarin ze worden aangeroepen. U ziet dat wanneer u het programma uitvoert, de taken niet altijd worden voltooid in de volgorde waarin ze zijn gemaakt en in afwachting zijn. Ze worden uitgevoerd wanneer ze worden gemaakt en een of meer taken kunnen worden voltooid voordat de methode de await-expressies bereikt.

Notitie

Als u dit project wilt voltooien, moet Visual Studio 2012 of hoger zijn geïnstalleerd en .NET Framework 4.5 of hoger op uw computer zijn geïnstalleerd.

Voor een ander voorbeeld dat meerdere taken tegelijk start, raadpleegt u Procedure: De Asynchrone walkthrough uitbreiden met behulp van Task.WhenAll (Visual Basic).

U kunt de code voor dit voorbeeld downloaden uit voorbeelden van ontwikkelaarscode.

Het project instellen

  1. Voer de volgende stappen uit om een WPF-toepassing in te stellen. U vindt gedetailleerde instructies voor deze stappen in Walkthrough: Accessing the Web by Using Async and Await (Visual Basic).

    • Maak een WPF-toepassing die een tekstvak en een knop bevat. Geef de knop startButtoneen naam en geef het tekstvak resultsTextBoxeen naam.

    • Voeg een verwijzing toe voor System.Net.Http.

    • Voeg in het bestand MainWindow.xaml.vb een Imports instructie toe voor System.Net.Http.

De code toevoegen

  1. Dubbelklik in het ontwerpvenster MainWindow.xaml op de knop om de startButton_Click gebeurtenis-handler te maken in MainWindow.xaml.vb.

  2. Kopieer de volgende code en plak deze in de hoofdtekst van startButton_Click MainWindow.xaml.vb.

    resultsTextBox.Clear()
    Await CreateMultipleTasksAsync()
    resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    

    De code roept een asynchrone methode aan, CreateMultipleTasksAsyncdie de toepassing aanstuurt.

  3. Voeg de volgende ondersteuningsmethoden toe aan het project:

    • ProcessURLAsync gebruikt een HttpClient methode om de inhoud van een website als bytematrix te downloaden. De ondersteuningsmethode wordt ProcessURLAsync vervolgens weergegeven en retourneert de lengte van de matrix.

    • DisplayResults geeft het aantal bytes in de bytematrix voor elke URL weer. Deze weergave wordt weergegeven wanneer elke taak klaar is met downloaden.

    Kopieer de volgende methoden en plak deze na de startButton_Click gebeurtenis-handler in MainWindow.xaml.vb.

    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 "https://".
        Dim displayURL = url.Replace("https://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
    
  4. Definieer ten slotte de methode CreateMultipleTasksAsync, waarmee de volgende stappen worden uitgevoerd.

    • De methode declareert een HttpClient object, dat u nodig hebt om toegang te krijgen tot de methode GetByteArrayAsync in ProcessURLAsync.

    • De methode maakt en start drie taken van het type Task<TResult>, waarbij TResult een geheel getal is. Wanneer elke taak is voltooid, DisplayResults worden de URL van de taak en de lengte van de gedownloade inhoud weergegeven. Omdat de taken asynchroon worden uitgevoerd, kan de volgorde waarin de resultaten worden weergegeven, afwijken van de volgorde waarin ze zijn gedeclareerd.

    • De methode wacht op de voltooiing van elke taak. Elke Await operator onderbreekt de uitvoering totdat CreateMultipleTasksAsync de wachtende taak is voltooid. De operator haalt ook de retourwaarde op uit de aanroep van ProcessURLAsync elke voltooide taak.

    • Wanneer de taken zijn voltooid en de waarden voor gehele getallen zijn opgehaald, wordt met de methode de lengte van de websites opgeteld en wordt het resultaat weergegeven.

    Kopieer de volgende methode en plak deze in uw oplossing.

    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/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/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
    
  5. Kies de F5-toets om het programma uit te voeren en kies vervolgens de knop Start .

    Voer het programma meerdere keren uit om te controleren of de drie taken niet altijd in dezelfde volgorde eindigen en of de volgorde waarin ze zijn voltooid niet noodzakelijkerwijs de volgorde is waarin ze zijn gemaakt en in afwachting zijn.

Opmerking

De volgende code bevat het volledige voorbeeld.

' 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/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/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 "https://".
        Dim displayURL = url.Replace("https://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
End Class

Zie ook