Przewodnik: uzyskiwanie dostępu do sieci Web przy użyciu Async i Await (Visual Basic)
Programy asynchroniczne można pisać łatwiej i intuicyjnie przy użyciu funkcji asynchronicznych/await. Możesz napisać kod asynchroniczny, który wygląda jak kod synchroniczny, i pozwolić kompilatorowi obsługiwać trudne funkcje wywołania zwrotnego i kontynuacje, które zwykle wiąże się z kodem asynchronicznym.
Aby uzyskać więcej informacji na temat funkcji asynchronicznej, zobacz Asynchroniczne programowanie za pomocą Async i Await (Visual Basic).
Ten przewodnik rozpoczyna się od synchronicznej aplikacji Windows Presentation Foundation (WPF), która sumuje liczbę bajtów na liście witryn internetowych. Następnie przewodnik konwertuje aplikację na rozwiązanie asynchroniczne przy użyciu nowych funkcji.
Aplikacje można opracowywać, wykonując przewodnik lub pobierając przykład z przeglądarki przykładowej platformy .NET. Przykładowy kod znajduje się w projekcie SerialAsyncExample .
W tym przewodniku wykonasz następujące zadania:
- Tworzenie aplikacji WPF
- Projektowanie prostego systemu WPF MainWindow
- Dodawanie odwołania
- Dodawanie niezbędnych instrukcji Import
- Tworzenie aplikacji synchronicznej
- Testowanie rozwiązania synchronicznego
- Konwertowanie metody GetURLContents na metodę asynchroniczną
- Konwertowanie sumPageSizes na metodę asynchroniczną
- Konwertowanie startButton_Click na metodę asynchroniczną
- Testowanie rozwiązania asynchronicznego
- Zastąp metodę GetURLContentsAsync metodą .NET Framework
Zobacz sekcję Przykład , aby zapoznać się z kompletnym przykładem asynchronicznym.
Wymagania wstępne
Na komputerze musi być zainstalowany program Visual Studio 2012 lub nowszy. Aby uzyskać więcej informacji, zobacz stronę Pliki do pobrania programu Visual Studio.
Tworzenie aplikacji WPF
Uruchom program Visual Studio.
Na pasku menu wybierz pozycję Plik, Nowy, Projekt.
Zostanie otwarte okno dialogowe Nowy projekt .
W okienku Zainstalowane szablony wybierz pozycję Visual Basic, a następnie wybierz pozycję Aplikacja WPF z listy typów projektów.
W polu tekstowym Nazwa wprowadź ciąg
AsyncExampleWPF
, a następnie wybierz przycisk OK.Nowy projekt zostanie wyświetlony w Eksplorator rozwiązań.
Projektowanie prostego systemu WPF MainWindow
W edytorze programu Visual Studio Code wybierz kartę MainWindow.xaml .
Jeśli okno Przybornik nie jest widoczne, otwórz menu Widok, a następnie wybierz pozycję Przybornik.
Dodaj kontrolkę Przycisk i kontrolkę TextBox do okna MainWindow.
Wyróżnij kontrolkę TextBox i w oknie Właściwości ustaw następujące wartości:
Ustaw właściwość Name na
resultsTextBox
.Ustaw właściwość Height na 250.
Ustaw właściwość Width na 500.
Na karcie Tekst określ czcionkę monospacedową, taką jak Konsola Lucida lub Global Monospace.
Wyróżnij kontrolkę Przycisk i w oknie Właściwości ustaw następujące wartości:
Ustaw właściwość Name na
startButton
.Zmień wartość właściwości Content z Button na Start.
Umieść pole tekstowe i przycisk tak, aby oba te elementy pojawiały się w oknie MainWindow .
Aby uzyskać więcej informacji na temat projektanta XAML WPF, zobacz Tworzenie interfejsu użytkownika przy użyciu projektanta XAML.
Dodawanie odwołania
W Eksplorator rozwiązań wyróżnij nazwę projektu.
Na pasku menu wybierz pozycję Projekt, Dodaj odwołanie.
Zostanie wyświetlone okno dialogowe Menedżer odwołań.
W górnej części okna dialogowego sprawdź, czy projekt jest przeznaczony dla programu .NET Framework 4.5 lub nowszego.
W obszarze Zestawy wybierz pozycję Struktura, jeśli nie została jeszcze wybrana.
Na liście nazw zaznacz pole wyboru System.Net.Http .
Wybierz przycisk OK, aby zamknąć okno dialogowe.
Dodawanie niezbędnych instrukcji Import
W Eksplorator rozwiązań otwórz menu skrótów dla MainWindow.xaml.vb, a następnie wybierz pozycję Wyświetl kod.
Dodaj następujące
Imports
instrukcje w górnej części pliku kodu, jeśli jeszcze nie są obecne.Imports System.Net.Http Imports System.Net Imports System.IO
Tworzenie aplikacji synchronicznej
W oknie projektowania MainWindow.xaml kliknij dwukrotnie przycisk Start , aby utworzyć procedurę
startButton_Click
obsługi zdarzeń w MainWindow.xaml.vb.W MainWindow.xaml.vb skopiuj następujący kod do treści :
startButton_Click
resultsTextBox.Clear() SumPageSizes() resultsTextBox.Text &= vbCrLf & "Control returned to startButton_Click."
Kod wywołuje metodę, która napędza aplikację ,
SumPageSizes
i wyświetla komunikat, gdy kontrolka powróci dostartButton_Click
.Kod rozwiązania synchronicznego zawiera następujące cztery metody:
SumPageSizes
, który pobiera listę adresów URL stron internetowych zSetUpURLList
, a następnie wywołujeGetURLContents
iDisplayResults
przetwarza każdy adres URL.SetUpURLList
, który tworzy i zwraca listę adresów internetowych.GetURLContents
, który pobiera zawartość każdej witryny internetowej i zwraca zawartość jako tablicę bajtów.DisplayResults
, który wyświetla liczbę bajtów w tablicy bajtów dla każdego adresu URL.
Skopiuj następujące cztery metody, a następnie wklej je w programie
startButton_Click
obsługi zdarzeń w MainWindow.xaml.vb:Private Sub SumPageSizes() ' Make a list of web addresses. Dim urlList As List(Of String) = SetUpURLList() Dim total = 0 For Each url In urlList ' GetURLContents returns the contents of url as a byte array. Dim urlContents As Byte() = GetURLContents(url) DisplayResults(url, urlContents) ' Update the total. total += urlContents.Length Next ' Display the total count for all of the web addresses. resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "Total bytes returned: {0}" & vbCrLf, total) End Sub Private Function SetUpURLList() As List(Of String) Dim urls = New List(Of String) From { "https://msdn.microsoft.com/library/windows/apps/br211380.aspx", "https://msdn.microsoft.com", "https://msdn.microsoft.com/library/hh290136.aspx", "https://msdn.microsoft.com/library/ee256749.aspx", "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 Private Function GetURLContents(url As String) As Byte() ' The downloaded resource ends up in the variable named content. Dim content = New MemoryStream() ' Initialize an HttpWebRequest for the current URL. Dim webReq = CType(WebRequest.Create(url), HttpWebRequest) ' Send the request to the Internet resource and wait for ' the response. ' Note: you can't use HttpWebRequest.GetResponse in a Windows Store app. Using response As WebResponse = webReq.GetResponse() ' Get the data stream that is associated with the specified URL. Using responseStream As Stream = response.GetResponseStream() ' Read the bytes in responseStream and copy them to content. responseStream.CopyTo(content) End Using End Using ' Return the result as a byte array. Return content.ToArray() 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
Testowanie rozwiązania synchronicznego
Wybierz F5, aby uruchomić program, a następnie wybierz przycisk Uruchom .
Powinny zostać wyświetlone dane wyjściowe podobne do poniższej listy:
msdn.microsoft.com/library/windows/apps/br211380.aspx 383832 msdn.microsoft.com 33964 msdn.microsoft.com/library/hh290136.aspx 225793 msdn.microsoft.com/library/ee256749.aspx 143577 msdn.microsoft.com/library/hh290138.aspx 237372 msdn.microsoft.com/library/hh290140.aspx 128279 msdn.microsoft.com/library/dd470362.aspx 157649 msdn.microsoft.com/library/aa578028.aspx 204457 msdn.microsoft.com/library/ms404677.aspx 176405 msdn.microsoft.com/library/ff730837.aspx 143474 Total bytes returned: 1834802 Control returned to startButton_Click.
Zwróć uwagę, że wyświetlenie liczby trwa kilka sekund. W tym czasie wątek interfejsu użytkownika jest blokowany podczas oczekiwania na pobranie żądanych zasobów. W związku z tym nie można przenosić, maksymalizować, zminimalizować ani nawet zamknąć okna wyświetlania po wybraniu przycisku Uruchom . Te działania kończą się niepowodzeniem, dopóki liczba bajtów nie zacznie się pojawiać. Jeśli witryna internetowa nie odpowiada, nie masz żadnych wskazówek, które witryny nie powiodły się. Trudno jest nawet przestać czekać i zamknąć program.
Konwertowanie metody GetURLContents na metodę asynchroniczną
Aby przekonwertować rozwiązanie synchroniczne na rozwiązanie asynchroniczne, najlepszym miejscem do uruchomienia jest
GetURLContents
to, że wywołania HttpWebRequest.GetResponse metody i Stream.CopyTo metody to miejsce, w którym aplikacja uzyskuje dostęp do sieci Web. Program .NET Framework ułatwia konwersję, dostarczając asynchroniczne wersje obu metod.Aby uzyskać więcej informacji na temat metod używanych w
GetURLContents
programie , zobacz WebRequest.Uwaga
Podczas opracowywania kroków opisanych w tym przewodniku pojawia się kilka błędów kompilatora. Możesz je zignorować i kontynuować z przewodnikiem.
Zmień metodę wywoływaną w trzecim wierszu
GetURLContents
zGetResponse
na asynchroniczną metodę opartą na GetResponseAsync zadaniach.Using response As WebResponse = webReq.GetResponseAsync()
GetResponseAsync
zwraca wartość Task<TResult>. W tym przypadku zmienna zwracana przez zadanie ,TResult
ma typ WebResponse. Zadanie jest obietnicą utworzenia rzeczywistegoWebResponse
obiektu po pobraniu żądanych danych, a zadanie zostało uruchomione do ukończenia.Aby pobrać
WebResponse
wartość z zadania, zastosuj operator Await do wywołaniaGetResponseAsync
metody , jak pokazano w poniższym kodzie.Using response As WebResponse = Await webReq.GetResponseAsync()
Operator
Await
zawiesza wykonywanie bieżącej metody ,GetURLContents
aż do ukończenia oczekiwanego zadania. W międzyczasie kontrolka powraca do obiektu wywołującego bieżącej metody. W tym przykładzie bieżąca metoda toGetURLContents
, a obiekt wywołujący toSumPageSizes
. Po zakończeniu zadania obiecanyWebResponse
obiekt jest generowany jako wartość oczekiwanego zadania i przypisany do zmiennejresponse
.Poprzednie stwierdzenie można oddzielić od następujących dwóch stwierdzeń, aby wyjaśnić, co się stanie.
Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync() Using response As WebResponse = Await responseTask
Wywołanie metody zwraca
webReq.GetResponseAsync
wartośćTask(Of WebResponse)
lubTask<WebResponse>
.Await
Następnie operator jest stosowany do zadania w celu pobraniaWebResponse
wartości.Jeśli metoda asynchronizna ma pracę, która nie zależy od ukończenia zadania, metoda może kontynuować pracę między tymi dwiema instrukcjami, po wywołaniu metody asynchronicznej i przed zastosowaniem operatora await. Przykłady można znaleźć w temacie How to: Make Multiple Web Requests in Parallel by Using Async and Await (Visual Basic) and How to: Extend the Async Walkthrough by Using Task.WhenAll (Visual Basic) ( Porady: rozszerzanie przewodnika asynchronicznego przy użyciu funkcji Task.WhenAll (Visual Basic)).
Ponieważ operator został dodany
Await
w poprzednim kroku, występuje błąd kompilatora. Operator może być używany tylko w metodach oznaczonych modyfikatorem Async . Ignoruj błąd podczas powtarzania kroków konwersji, aby zastąpić wywołanieCopyTo
metody wywołaniem metodyCopyToAsync
.Zmień nazwę metody, która jest wywoływana na CopyToAsync.
Metoda
CopyTo
orCopyToAsync
kopiuje bajty do argumentucontent
, i nie zwraca znaczącej wartości. W wersji synchronicznej wywołanie metodyCopyTo
to prosta instrukcja, która nie zwraca wartości. Wersja asynchroniczna ,CopyToAsync
zwraca wartość Task. Zadanie działa jak "Task(void)" i umożliwia oczekiwanie na metodę. ZastosujAwait
metodę lubawait
do wywołaniaCopyToAsync
metody , jak pokazano w poniższym kodzie.Await responseStream.CopyToAsync(content)
Poprzednia instrukcja skraca następujące dwa wiersze kodu.
' CopyToAsync returns a Task, not a Task<T>. Dim copyTask As Task = responseStream.CopyToAsync(content) ' When copyTask is completed, content contains a copy of ' responseStream. Await copyTask
Wszystko, co pozostało do zrobienia,
GetURLContents
to dostosowanie podpisu metody. Operator można używaćAwait
tylko w metodach oznaczonych modyfikatorem Async . Dodaj modyfikator, aby oznaczyć metodę jako metodę asynchroniową, jak pokazano w poniższym kodzie.Private Async Function GetURLContents(url As String) As Byte()
Zwracany typ metody asynchronicznej może mieć Taskwartość , Task<TResult>. W języku Visual Basic metoda musi być
Function
metodą, która zwraca wartośćTask
lubTask(Of T)
, lub metoda musi byćSub
metodą .Sub
Zazwyczaj metoda jest używana tylko w asynchronicznej procedurze obsługi zdarzeń, gdzieSub
jest to wymagane. W innych przypadkach należy użyćTask(T)
instrukcji Return , która zwraca wartość typu T, a jeśliTask
ukończona metoda nie zwraca znaczącej wartości.Aby uzyskać więcej informacji, zobacz Async Return Types (Visual Basic).
Metoda
GetURLContents
ma instrukcję return, a instrukcja zwraca tablicę bajtów. W związku z tym zwracany typ wersji asynchronizowanej to Task(T), gdzie T jest tablicą bajtów. Wprowadź następujące zmiany w podpisie metody:Zmień typ zwracany na
Task(Of Byte())
.Zgodnie z konwencją metody asynchroniczne mają nazwy, które kończą się na "Async", więc zmień nazwę metody
GetURLContentsAsync
.
Poniższy kod przedstawia te zmiany.
Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
Po wprowadzeniu tych kilku zmian konwersja
GetURLContents
metody asynchronicznej jest zakończona.
Konwertowanie sumPageSizes na metodę asynchroniczną
Powtórz kroki z poprzedniej procedury dla elementu
SumPageSizes
. Najpierw zmień wywołanie naGetURLContents
asynchroniczne.Zmień nazwę metody wywoływanej z
GetURLContents
naGetURLContentsAsync
, jeśli jeszcze tego nie zrobiono.Zastosuj
Await
do zadania, któreGetURLContentsAsync
zwraca, aby uzyskać wartość tablicy bajtów.
Poniższy kod przedstawia te zmiany.
Dim urlContents As Byte() = Await GetURLContentsAsync(url)
Poprzednie przypisanie skraca następujące dwa wiersze kodu.
' GetURLContentsAsync returns a task. At completion, the task ' produces a byte array. Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url) Dim urlContents As Byte() = Await getContentsTask
Wprowadź następujące zmiany w podpisie metody:
Oznacz metodę za pomocą
Async
modyfikatora.Dodaj ciąg "Async" do nazwy metody.
Nie ma zmiennej zwracanej przez zadanie T, tym razem, ponieważ
SumPageSizesAsync
nie zwraca wartości T. (metoda nieReturn
ma instrukcji). Jednak metoda musi zwrócić wartośćTask
, aby można było oczekiwać. W związku z tym zmień typ metody zSub
naFunction
. Zwracany typ funkcji toTask
.
Poniższy kod przedstawia te zmiany.
Private Async Function SumPageSizesAsync() As Task
Konwersja na
SumPageSizes
SumPageSizesAsync
jest zakończona.
Konwertowanie startButton_Click na metodę asynchroniczną
W procedurze obsługi zdarzeń zmień nazwę wywoływanej metody z
SumPageSizes
naSumPageSizesAsync
, jeśli jeszcze tego nie zrobiono.Ponieważ
SumPageSizesAsync
jest metodą asynchroniową, zmień kod w procedurze obsługi zdarzeń, aby oczekiwać na wynik.Wywołanie
SumPageSizesAsync
metody dubluje wywołanie metodyCopyToAsync
w metodzie .GetURLContentsAsync
Wywołanie zwraca wartośćTask
, aTask(T)
nie .Podobnie jak w poprzednich procedurach, można przekonwertować wywołanie przy użyciu jednej instrukcji lub dwóch instrukcji. Poniższy kod przedstawia te zmiany.
' One-step async call. Await SumPageSizesAsync() ' Two-step async call. Dim sumTask As Task = SumPageSizesAsync() Await sumTask
Aby zapobiec przypadkowemu ponownemu wprowadzeniu operacji, dodaj następującą instrukcję w górnej
startButton_Click
części, aby wyłączyć przycisk Uruchom .' Disable the button until the operation is complete. startButton.IsEnabled = False
Można ponownie przywrócić przycisk na końcu programu obsługi zdarzeń.
' Reenable the button in case you want to run the operation again. startButton.IsEnabled = True
Aby uzyskać więcej informacji na temat ponownego uwierzytelniania, zobacz Obsługa ponownej reentrancy w aplikacjach asynchronicznych (Visual Basic).
Na koniec dodaj
Async
modyfikator do deklaracji, aby program obsługi zdarzeń mógł oczekiwać naSumPagSizesAsync
.Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
Zazwyczaj nazwy programów obsługi zdarzeń nie są zmieniane. Zwracany typ nie jest zmieniany na
Task
, ponieważ procedury obsługi zdarzeń muszą byćSub
procedurami w Visual Basic.Konwersja projektu z synchronicznego na asynchroniczne przetwarzanie jest zakończona.
Testowanie rozwiązania asynchronicznego
Wybierz F5, aby uruchomić program, a następnie wybierz przycisk Uruchom .
Powinny zostać wyświetlone dane wyjściowe podobne do danych wyjściowych rozwiązania synchronicznego. Zwróć jednak uwagę na następujące różnice.
Wyniki nie występują jednocześnie po zakończeniu przetwarzania. Na przykład oba programy zawierają wiersz,
startButton_Click
który czyści pole tekstowe. Intencją jest wyczyszczenie pola tekstowego między przebiegami po drugim wybraniu przycisku Start po pojawieniu się jednego zestawu wyników. W wersji synchronicznej pole tekstowe jest czyszczone tuż przed wyświetleniem liczników po raz drugi, po zakończeniu pobierania i wątku interfejsu użytkownika można wykonać inne czynności. W wersji asynchronicznej pole tekstowe jest czyszczane natychmiast po wybraniu przycisku Uruchom .Co najważniejsze, wątek interfejsu użytkownika nie jest blokowany podczas pobierania. Okno można przenosić lub zmieniać rozmiar, gdy zasoby internetowe są pobierane, liczone i wyświetlane. Jeśli jedna z witryn internetowych działa wolno lub nie odpowiada, możesz anulować operację, wybierając przycisk Zamknij (x w czerwonym polu w prawym górnym rogu).
Zastąp metodę GetURLContentsAsync metodą .NET Framework
Program .NET Framework udostępnia wiele metod asynchronicznych, których można użyć. Jedna z nich, HttpClient.GetByteArrayAsync(String) metoda, robi tylko to, czego potrzebujesz w tym przewodniku. Można jej użyć zamiast
GetURLContentsAsync
metody utworzonej we wcześniejszej procedurze.Pierwszym krokiem jest utworzenie HttpClient obiektu w metodzie
SumPageSizesAsync
. Dodaj następującą deklarację na początku metody .' 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}
W
SumPageSizesAsync
pliku zastąp wywołanie metody wywołaniemGetURLContentsAsync
HttpClient
metody .Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
Usuń lub oznacz jako komentarz metodę
GetURLContentsAsync
, którą napisałeś.Wybierz F5, aby uruchomić program, a następnie wybierz przycisk Uruchom .
Zachowanie tej wersji projektu powinno być zgodne z zachowaniem, które opisano w procedurze "Aby przetestować rozwiązanie asynchroniczne", ale z jeszcze mniejszym nakładem pracy.
Przykład
Poniżej przedstawiono pełny przykład przekonwertowanego rozwiązania asynchronicznego korzystającego z metody asynchronicznej GetURLContentsAsync
. Zwróć uwagę, że silnie przypomina oryginalne, synchroniczne rozwiązanie.
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
' Disable the button until the operation is complete.
startButton.IsEnabled = False
resultsTextBox.Clear()
'' One-step async call.
Await SumPageSizesAsync()
' Two-step async call.
'Dim sumTask As Task = SumPageSizesAsync()
'Await sumTask
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
' Reenable the button in case you want to run the operation again.
startButton.IsEnabled = True
End Sub
Private Async Function SumPageSizesAsync() As Task
' Make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
Dim total = 0
For Each url In urlList
Dim urlContents As Byte() = Await GetURLContentsAsync(url)
' The previous line abbreviates the following two assignment statements.
'//<snippet21>
' GetURLContentsAsync returns a task. At completion, the task
' produces a byte array.
'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url)
'Dim urlContents As Byte() = Await getContentsTask
DisplayResults(url, urlContents)
' Update the total.
total += urlContents.Length
Next
' Display the total count for all of the websites.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
End Function
Private Function SetUpURLList() As List(Of String)
Dim urls = New List(Of String) From
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"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
Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
' The downloaded resource ends up in the variable named content.
Dim content = New MemoryStream()
' Initialize an HttpWebRequest for the current URL.
Dim webReq = CType(WebRequest.Create(url), HttpWebRequest)
' Send the request to the Internet resource and wait for
' the response.
Using response As WebResponse = Await webReq.GetResponseAsync()
' The previous statement abbreviates the following two statements.
'Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync()
'Using response As WebResponse = Await responseTask
' Get the data stream that is associated with the specified URL.
Using responseStream As Stream = response.GetResponseStream()
' Read the bytes in responseStream and copy them to content.
Await responseStream.CopyToAsync(content)
' The previous statement abbreviates the following two statements.
' CopyToAsync returns a Task, not a Task<T>.
'Dim copyTask As Task = responseStream.CopyToAsync(content)
' When copyTask is completed, content contains a copy of
' responseStream.
'Await copyTask
End Using
End Using
' Return the result as a byte array.
Return content.ToArray()
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
Poniższy kod zawiera pełny przykład rozwiązania, które używa HttpClient
metody GetByteArrayAsync
.
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
resultsTextBox.Clear()
' Disable the button until the operation is complete.
startButton.IsEnabled = False
' One-step async call.
Await SumPageSizesAsync()
' Two-step async call.
'Dim sumTask As Task = SumPageSizesAsync()
'Await sumTask
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
' Reenable the button in case you want to run the operation again.
startButton.IsEnabled = True
End Sub
Private Async Function SumPageSizesAsync() 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}
' Make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
Dim total = 0
For Each url In urlList
' GetByteArrayAsync returns a task. At completion, the task
' produces a byte array.
Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
' The following two lines can replace the previous assignment statement.
'Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
'Dim urlContents As Byte() = Await getContentsTask
DisplayResults(url, urlContents)
' Update the total.
total += urlContents.Length
Next
' Display the total count for all of the websites.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
End Function
Private Function SetUpURLList() As List(Of String)
Dim urls = New List(Of String) From
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"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
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
Zobacz też
- Przykład asynchroniczny: uzyskiwanie dostępu do przewodnika internetowego (C# i Visual Basic)
- Await, operator
- Async
- Programowanie asynchroniczne z funkcją Async i Await (Visual Basic)
- Asynchroniczne typy zwracane (Visual Basic)
- Programowanie asynchroniczne oparte na zadaniach (TAP)
- Porady: rozszerzanie przewodnika asynchronicznego przy użyciu elementu Task.WhenAll (Visual Basic)
- Porady: równoległe tworzenie wielu żądań internetowych przy użyciu Async i Await (Visual Basic)