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
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
startButton
een naam en geef het tekstvakresultsTextBox
een naam.Voeg een verwijzing toe voor System.Net.Http.
Voeg in het bestand MainWindow.xaml.vb een
Imports
instructie toe voorSystem.Net.Http
.
De code toevoegen
Dubbelklik in het ontwerpvenster MainWindow.xaml op de knop om de
startButton_Click
gebeurtenis-handler te maken in MainWindow.xaml.vb.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,
CreateMultipleTasksAsync
die de toepassing aanstuurt.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 wordtProcessURLAsync
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
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 inProcessURLAsync
.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 totdatCreateMultipleTasksAsync
de wachtende taak is voltooid. De operator haalt ook de retourwaarde op uit de aanroep vanProcessURLAsync
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
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