Porady: równoległe tworzenie wielu żądań internetowych przy użyciu Async i Await (Visual Basic)
W metodzie asynchronicznej zadania są uruchamiane po ich utworzeniu. Operator Await jest stosowany do zadania w punkcie w metodzie, w której przetwarzanie nie może być kontynuowane do momentu zakończenia zadania. Często zadanie jest oczekiwane natychmiast po jego utworzeniu, jak pokazano w poniższym przykładzie.
Dim result = Await someWebAccessMethodAsync(url)
Można jednak oddzielić tworzenie zadania od oczekiwania na zadanie, jeśli program ma inną pracę do wykonania, która nie zależy od ukończenia zadania.
' 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
Między uruchomieniem zadania i oczekiwaniem na nie można uruchomić inne zadania. Dodatkowe zadania są uruchamiane równolegle, ale nie są tworzone żadne dodatkowe wątki.
Poniższy program uruchamia trzy asynchroniczne pliki do pobrania w Internecie, a następnie oczekuje na nie w kolejności, w której są wywoływane. Zwróć uwagę, że po uruchomieniu programu zadania nie zawsze kończą się w kolejności, w której są tworzone i oczekiwane. Zaczynają działać po ich utworzeniu, a co najmniej jedno zadanie może zakończyć się przed osiągnięciem wyrażeń await przez metodę .
Uwaga
Aby ukończyć ten projekt, na komputerze musi być zainstalowany program Visual Studio 2012 lub nowszy oraz program .NET Framework 4.5 lub nowszy.
Aby zapoznać się z innym przykładem, który uruchamia wiele zadań w tym samym czasie, zobacz How to: Extend thesync Walkthrough by Using Task.WhenAll (Visual Basic)( Jak rozszerzyć przewodnik asynchroniczny przy użyciu task.WhenAll (Visual Basic).
Możesz pobrać kod dla tego przykładu z sekcji Przykłady kodu dla deweloperów.
Aby skonfigurować projekt
Aby skonfigurować aplikację WPF, wykonaj następujące kroki. Szczegółowe instrukcje można znaleźć w temacie Przewodnik: uzyskiwanie dostępu do sieci Web przy użyciu Async i Await (Visual Basic).
Utwórz aplikację WPF zawierającą pole tekstowe i przycisk. Nadaj przyciskowi
startButton
nazwę i nadaj nazwę poluresultsTextBox
tekstowego .Dodaj odwołanie dla elementu System.Net.Http.
W pliku MainWindow.xaml.vb dodaj instrukcję
Imports
dla elementuSystem.Net.Http
.
Aby dodać kod
W oknie projektowania MainWindow.xaml kliknij dwukrotnie przycisk, aby utworzyć procedurę
startButton_Click
obsługi zdarzeń w MainWindow.xaml.vb.Skopiuj poniższy kod i wklej go do treści
startButton_Click
pliku w MainWindow.xaml.vb.resultsTextBox.Clear() Await CreateMultipleTasksAsync() resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
Kod wywołuje metodę asynchroniczną ,
CreateMultipleTasksAsync
która napędza aplikację.Dodaj następujące metody obsługi do projektu:
ProcessURLAsync
HttpClient Metoda używa metody do pobrania zawartości witryny internetowej jako tablicy bajtów. Metoda obsługi,ProcessURLAsync
a następnie wyświetla i zwraca długość tablicy.DisplayResults
wyświetla liczbę bajtów w tablicy bajtów dla każdego adresu URL. Ten ekran jest wyświetlany po zakończeniu pobierania każdego zadania.
Skopiuj następujące metody i wklej je po procedurze
startButton_Click
obsługi zdarzeń w 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
Na koniec zdefiniuj metodę
CreateMultipleTasksAsync
, która wykonuje następujące kroki.Metoda deklaruje
HttpClient
obiekt, do którego należy uzyskać dostęp w metodzie GetByteArrayAsync .ProcessURLAsync
Metoda tworzy i uruchamia trzy zadania typu Task<TResult>, gdzie
TResult
jest liczbą całkowitą. Po zakończeniuDisplayResults
każdego zadania wyświetla adres URL zadania i długość pobranej zawartości. Ponieważ zadania są uruchamiane asynchronicznie, kolejność wyświetlania wyników może różnić się od kolejności, w jakiej zostały zadeklarowane.Metoda oczekuje na ukończenie każdego zadania. Każdy
Await
operator zawiesza wykonywanieCreateMultipleTasksAsync
do momentu zakończenia oczekiwanego zadania. Operator pobiera również wartość zwracaną z wywołania doProcessURLAsync
z każdego ukończonego zadania.Po zakończeniu zadań i pobraniu wartości całkowitych metoda sumuje długości witryn internetowych i wyświetla wynik.
Skopiuj następującą metodę i wklej ją do rozwiązania.
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
Wybierz klawisz F5, aby uruchomić program, a następnie wybierz przycisk Uruchom .
Uruchom program kilka razy, aby sprawdzić, czy trzy zadania nie zawsze kończą się w tej samej kolejności i że kolejność ich zakończenia nie musi być kolejnością, w której są tworzone i oczekiwane.
Przykład
Poniższy kod zawiera pełny przykład.
' 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