Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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 , a następnie wybierz
AsyncExampleWPF.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
Importsinstrukcje 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_Clickobsługi zdarzeń w MainWindow.xaml.vb.W MainWindow.xaml.vb skopiuj następujący kod do treści :
startButton_ClickresultsTextBox.Clear() SumPageSizes() resultsTextBox.Text &= vbCrLf & "Control returned to startButton_Click."Kod wywołuje metodę, która napędza aplikację ,
SumPageSizesi 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łujeGetURLContentsiDisplayResultsprzetwarza 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_Clickobsł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
GetURLContentsto, ż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
GetURLContentsprogramie , 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
GetURLContentszGetResponsena asynchroniczną metodę opartą na GetResponseAsync zadaniach.Using response As WebResponse = webReq.GetResponseAsync()GetResponseAsynczwraca wartość Task<TResult>. W tym przypadku zmienna zwracana przez zadanie ,TResultma typ WebResponse. Zadanie jest obietnicą utworzenia rzeczywistegoWebResponseobiektu po pobraniu żądanych danych, a zadanie zostało uruchomione do ukończenia.Aby pobrać
WebResponsewartość z zadania, zastosuj operator Await do wywołaniaGetResponseAsyncmetody , jak pokazano w poniższym kodzie.Using response As WebResponse = Await webReq.GetResponseAsync()Operator
Awaitzawiesza wykonywanie bieżącej metody ,GetURLContentsaż 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 obiecanyWebResponseobiekt 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 responseTaskWywołanie metody zwraca
webReq.GetResponseAsyncwartośćTask(Of WebResponse)lubTask<WebResponse>.AwaitNastępnie operator jest stosowany do zadania w celu pobraniaWebResponsewartoś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
Awaitw 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łanieCopyTometody wywołaniem metodyCopyToAsync.Zmień nazwę metody, która jest wywoływana na CopyToAsync.
Metoda
CopyToorCopyToAsynckopiuje bajty do argumentucontent, i nie zwraca znaczącej wartości. W wersji synchronicznej wywołanie metodyCopyToto prosta instrukcja, która nie zwraca wartości. Wersja asynchroniczna ,CopyToAsynczwraca wartość Task. Zadanie działa jak "Task(void)" i umożliwia oczekiwanie na metodę. ZastosujAwaitmetodę lubawaitdo wywołaniaCopyToAsyncmetody , 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,
GetURLContentsto dostosowanie podpisu metody. Operator można używaćAwaittylko 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ć
Functionmetodą, która zwraca wartośćTasklubTask(Of T), lub metoda musi byćSubmetodą .SubZazwyczaj metoda jest używana tylko w asynchronicznej procedurze obsługi zdarzeń, gdzieSubjest to wymagane. W innych przypadkach należy użyćTask(T)instrukcji Return , która zwraca wartość typu T, a jeśliTaskukończona metoda nie zwraca znaczącej wartości.Aby uzyskać więcej informacji, zobacz Async Return Types (Visual Basic).
Metoda
GetURLContentsma 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
GetURLContentsmetody asynchronicznej jest zakończona.
Konwertowanie sumPageSizes na metodę asynchroniczną
Powtórz kroki z poprzedniej procedury dla elementu
SumPageSizes. Najpierw zmień wywołanie naGetURLContentsasynchroniczne.Zmień nazwę metody wywoływanej z
GetURLContentsnaGetURLContentsAsync, jeśli jeszcze tego nie zrobiono.Zastosuj
Awaitdo zadania, któreGetURLContentsAsynczwraca, 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 getContentsTaskWprowadź następujące zmiany w podpisie metody:
Oznacz metodę za pomocą
Asyncmodyfikatora.Dodaj ciąg "Async" do nazwy metody.
Nie ma zmiennej zwracanej przez zadanie T, tym razem, ponieważ
SumPageSizesAsyncnie zwraca wartości T. (metoda nieReturnma instrukcji). Jednak metoda musi zwrócić wartośćTask, aby można było oczekiwać. W związku z tym zmień typ metody zSubnaFunction. Zwracany typ funkcji toTask.
Poniższy kod przedstawia te zmiany.
Private Async Function SumPageSizesAsync() As TaskKonwersja na
SumPageSizesSumPageSizesAsyncjest zakończona.
Konwertowanie startButton_Click na metodę asynchroniczną
W procedurze obsługi zdarzeń zmień nazwę wywoływanej metody z
SumPageSizesnaSumPageSizesAsync, jeśli jeszcze tego nie zrobiono.Ponieważ
SumPageSizesAsyncjest metodą asynchroniową, zmień kod w procedurze obsługi zdarzeń, aby oczekiwać na wynik.Wywołanie
SumPageSizesAsyncmetody dubluje wywołanie metodyCopyToAsyncw metodzie .GetURLContentsAsyncWywoł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 sumTaskAby zapobiec przypadkowemu ponownemu wprowadzeniu operacji, dodaj następującą instrukcję w górnej
startButton_Clickczęści, aby wyłączyć przycisk Uruchom .' Disable the button until the operation is complete. startButton.IsEnabled = FalseMoż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 = TrueAby uzyskać więcej informacji na temat ponownego uwierzytelniania, zobacz Obsługa ponownej reentrancy w aplikacjach asynchronicznych (Visual Basic).
Na koniec dodaj
Asyncmodyfikator do deklaracji, aby program obsługi zdarzeń mógł oczekiwać naSumPagSizesAsync.Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.ClickZazwyczaj nazwy programów obsługi zdarzeń nie są zmieniane. Zwracany typ nie jest zmieniany na
Task, ponieważ procedury obsługi zdarzeń muszą byćSubprocedurami 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_Clickktó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
GetURLContentsAsyncmetody 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
SumPageSizesAsyncpliku zastąp wywołanie metody wywołaniemGetURLContentsAsyncHttpClientmetody .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)