Procedura dettagliata: Accesso al Web con Async e Await (Visual Basic)
È possibile scrivere programmi asincroni in modo più semplice e intuitivo usando le funzionalità async/await. È possibile scrivere codice asincrono simile al codice sincrono e consentire al compilatore di gestire le complesse funzioni di callback e continuazione tipiche del codice asincrono.
Per altre informazioni sulla funzionalità asincrona, vedere Programmazione asincrona con Async e Await (Visual Basic).
Questa procedura dettagliata inizia con l'esecuzione di un'applicazione Windows Presentation Foundation (WPF) sincrona che somma il numero di byte in un elenco di siti Web. La procedura dettagliata converte quindi l'applicazione in una soluzione asincrona usando le nuove funzionalità.
È possibile sviluppare le applicazioni completando la procedura dettagliata o scaricando l'esempio dal browser di esempio .NET. Il codice di esempio si trova nel progetto SerialAsyncExample.
Questa procedura dettagliata prevede l'esecuzione delle attività seguenti:
- Creare un'applicazione WPF
- Progettare una semplice WPF MainWindow
- Aggiungere un riferimento
- Aggiungere istruzioni Imports necessarie
- Creare un'applicazione sincrona
- Eseguire il test della soluzione sincrona
- Convertire GetURLContents in un metodo asincrono
- Convertire SumPageSizes in un metodo asincrono
- Convertire startButton_Click in un metodo asincrono
- Eseguire il test della soluzione asincrona
- Sostituire il metodo GetURLContentsAsync con un metodo .NET Framework
Vedere la sezione Esempio per l'esempio asincrono completo.
Prerequisiti
È necessario che sia installato nel computer Visual Studio 2012 o versione successiva. Per altre informazioni, vedere la pagina Download di Visual Studio.
Creare un'applicazione WPF
Avviare Visual Studio.
Nella barra dei menu scegliere File, Nuovo, Progetto.
Verrà visualizzata la finestra di dialogo Nuovo progetto .
Nel riquadro Modelli installati, scegliere Visual Basic e quindi scegliere Applicazione WPF nell'elenco dei tipi di progetto.
Nella casella di testo Nome immettere
AsyncExampleWPF
e quindi scegliere il pulsante OK.Il nuovo progetto verrà visualizzato in Esplora soluzioni.
Progettare una finestra WPF MainWindow semplice
Nell'Editor di codice di Visual Studio scegliere la scheda MainWindow.xaml .
Se la finestra Casella degli strumenti non è visibile, aprire il menu Visualizza e quindi scegliere Casella degli strumenti.
Aggiungere un controllo Button e un controllo TextBox alla finestra MainWindow.
Evidenziare il controllo TextBox e nella finestra Proprietà impostare i valori seguenti:
Impostare la proprietà Nome su
resultsTextBox
.Impostare la proprietà Height su 250.
Impostare la proprietà Width su 500.
Nel scheda Testo specificare un tipo di carattere a spaziatura fissa, ad esempio Lucida Console o Global Monospace.
Evidenziare il controllo Button e nella finestra Proprietà impostare i valori seguenti:
Impostare la proprietà Nome su
startButton
.Modificare il valore della proprietà Content da Button in Start.
Posizionare la casella di testo e il pulsante in modo che entrambi siano visualizzati nella finestra MainWindow.
Per altre informazioni su WPF XAML Designer, vedere Creazione di un'interfaccia utente tramite XAML Designer.
Aggiungere un riferimento
In Esplora soluzioni evidenziare il nome del progetto.
Nella barra dei menu scegliere Progetto, Aggiungi riferimento.
Verrà visualizzata la finestra di dialogo Gestione riferimenti.
Nella parte superiore della finestra di dialogo verificare che il progetto sia destinato a .NET Framework 4.5 o versione successiva.
Nell'area Assembly scegliere Framework se non è già selezionato.
Nell'elenco dei nomi selezionare la casella di controllo System.Net.Http.
Scegliere il pulsante OK per chiudere la finestra di dialogo.
Aggiungere istruzioni Imports necessarie
In Esplora soluzioni aprire il menu di scelta rapida per MainWindow.xaml.vb e quindi scegliere Visualizza codice.
Aggiungere le seguenti istruzioni
Imports
all'inizio del file di codice, se non sono già presenti.Imports System.Net.Http Imports System.Net Imports System.IO
Creare un'applicazione sincrona
Nella finestra di progettazione MainWindow.xaml fare doppio clic sul pulsante Start per creare il gestore eventi
startButton_Click
in MainWindow.xaml.vb.In MainWindow.xaml.vb copiare il codice seguente nel corpo di
startButton_Click
:resultsTextBox.Clear() SumPageSizes() resultsTextBox.Text &= vbCrLf & "Control returned to startButton_Click."
Il codice chiama il metodo che controlla l'applicazione
SumPageSizes
e visualizza un messaggio quando il controllo torna astartButton_Click
.Il codice per la soluzione sincrona contiene i quattro metodi seguenti:
SumPageSizes
, che ottiene un elenco di URL delle pagine Web daSetUpURLList
e quindi chiamaGetURLContents
eDisplayResults
per elaborare ogni URL.SetUpURLList
, che crea e restituisce un elenco di indirizzi web.GetURLContents
, che scarica il contenuto di ogni sito Web e restituisce il contenuto come matrice di byte.DisplayResults
, che visualizza il numero di byte nella matrice di byte per ogni URL.
Copiare i quattro metodi seguenti e incollarli nel gestore eventi
startButton_Click
in 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
Eseguire il test della soluzione sincrona
Premere il tasto F5 per eseguire il programma e quindi scegliere il pulsante Start .
Verrà visualizzato un output simile all'elenco seguente:
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.
Si noti che sono necessari alcuni secondi per visualizzare i conteggi. Durante tale periodo, il thread dell'interfaccia utente viene bloccato mentre attende il download delle risorse richieste. Di conseguenza, è possibile spostare, ingrandire, ridurre o chiudere la finestra di visualizzazione dopo aver scelto il pulsante Start. Queste operazioni hanno esito negativo finché non vengono visualizzati i conteggi dei byte. Se un sito Web non risponde, non si ha alcuna indicazione relativa al sito con esito negativo. È inoltre difficile interrompere l'attesa e chiudere il programma.
Convertire GetURLContents in un metodo asincrono
Per convertire la soluzione sincrona in una soluzione asincrona, il punto di partenza migliore è in
GetURLContents
perché le chiamate al metodo HttpWebRequest.GetResponse e al metodo Stream.CopyTo sono i punti in cui l'applicazione accede al Web. .NET Framework semplifica la conversione fornendo versioni asincrone di entrambi i metodi.Per altre informazioni sui modelli usati in
GetURLContents
, vedere WebRequest.Nota
Mentre si esegue la procedura descritta in questa procedura dettagliata, vengono visualizzati diversi errori del compilatore. È possibile ignorarli e continuare con la procedura dettagliata.
Modificare il metodo chiamato nella terza riga di
GetURLContents
daGetResponse
nel metodo asincrono basato su attività GetResponseAsync.Using response As WebResponse = webReq.GetResponseAsync()
GetResponseAsync
restituisce Task<TResult>. In questo caso, la variabile di restituzione dell'attività,TResult
, è di tipo WebResponse. L'attività rappresenta una promessa di creazione di un oggettoWebResponse
effettivo dopo il download dei dati richiesti e il completamento dell'esecuzione dell'attività.Per recuperare il valore
WebResponse
dall'attività, applicare un operatore await alla chiamata diGetResponseAsync
, come mostrato nel codice riportato di seguito.Using response As WebResponse = Await webReq.GetResponseAsync()
L'operatore
GetURLContents
sospende l'esecuzione del metodo correnteAwait
fino al completamento dell'attività attesa. Nel frattempo il controllo viene restituito al chiamante del metodo asincrono. In questo esempio, il metodo corrente èGetURLContents
e il chiamante èSumPageSizes
. Quando l'attività è terminata, l'oggetto promessoWebResponse
viene generato come valore dell'attività attesa e assegnato alla variabileresponse
.L'istruzione precedente può essere suddivisa nelle due istruzioni seguenti per chiarire cosa accade.
Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync() Using response As WebResponse = Await responseTask
La chiamata a
webReq.GetResponseAsync
restituisceTask(Of WebResponse)
oTask<WebResponse>
. Viene quindi applicato un operatoreAwait
all'attività per recuperare il valoreWebResponse
.Se il metodo asincrono ha operazioni da eseguire che non dipendono dal completamento dell'attività, il metodo può continuare l'esecuzione tra queste due istruzioni dopo la chiamata al metodo asincrono e prima che venga applicato l'operatore await. Per esempi, vedere Procedura: Effettuare più richieste Web in parallelo tramite Async e Await (Visual Basic) e Procedura: Estendere la procedura dettagliata asincrona tramite Task.WhenAll (Visual Basic).
Poiché è stato aggiunto l'operatore
Await
nel passaggio precedente, verrà generato un errore del compilatore. L'operatore può essere usato solo nei metodi contrassegnati con il modificatore Async. Ignorare l'errore mentre vengono ripetuti i passaggi di conversione per sostituire la chiamata aCopyTo
con una chiamata aCopyToAsync
.Modificare il nome del metodo chiamato in CopyToAsync.
Il metodo
CopyTo
oCopyToAsync
copia i byte nel relativo argomentocontent
e non restituisce un valore significativo. Nella versione sincrona, la chiamata aCopyTo
è un'istruzione semplice che non restituisce un valore. La versione asincronaCopyToAsync
restituisce Task. L'attività è analoga a "Task(void)" e consente l'attesa del metodo. ApplicareAwait
oawait
alla chiamata aCopyToAsync
, come mostrato nel codice riportato di seguito.Await responseStream.CopyToAsync(content)
L'istruzione precedente abbrevia le due righe di codice riportate di seguito.
' 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
A questo punto, non rimane che modificare la firma del metodo in
GetURLContents
. È possibile usare l'operatoreAwait
solo nei metodi contrassegnati con il modificatore Async. Aggiungere il modificatore per contrassegnare il metodo come metodo async, come mostrato nel codice riportato di seguito.Private Async Function GetURLContents(url As String) As Byte()
Il tipo restituito di un metodo asincrono può essere solo Task, Task<TResult>. In Visual Basic, il metodo deve essere
Function
che restituisceTask
oTask(Of T)
oppure il metodo deve essereSub
. In genere, un metodoSub
viene usato solo in un gestore eventi asincrono, in cui è necessarioSub
. In altri casi è possibile usareTask(T)
se il metodo completato include un'istruzione Return che restituisce un valore di tipo T e si usaTask
se il metodo completato non restituisce un valore significativo.Per altre informazioni, vedere Tipi restituiti asincroni (Visual Basic).
Il metodo
GetURLContents
dispone di un'istruzione return che restituisce una matrice di byte. Pertanto, il tipo restituito della versione asincrona è Task(T), dove T è una matrice di byte. Apportare le modifiche seguenti nella firma del metodo:Cambiare il tipo restituito in
Task(Of Byte())
.Per convenzione, i metodi asincroni presentano nomi che terminano in "Async". Rinominare pertanto il metodo
GetURLContentsAsync
.
Nel codice seguente sono illustrate queste modifiche.
Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
Dopo aver apportato queste modifiche, la conversione di
GetURLContents
in un metodo asincrono è completa.
Convertire SumPageSizes in un metodo asincrono
Ripetere i passaggi della procedura precedente per
SumPageSizes
. In primo luogo, modificare la chiamata aGetURLContents
in una chiamata asincrona.Modificare il nome del metodo chiamato da
GetURLContents
inGetURLContentsAsync
, se non è ancora stato fatto.Applicare
Await
all'attività restituita daGetURLContentsAsync
per ottenere il valore della matrice di byte.
Nel codice seguente sono illustrate queste modifiche.
Dim urlContents As Byte() = Await GetURLContentsAsync(url)
L'assegnazione precedente abbrevia le due righe di codice riportate di seguito.
' 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
Apportare le modifiche seguenti nella firma del metodo:
Contrassegnare il metodo con il modificatore
Async
.Aggiungere "Async" al nome del metodo.
In questo caso non esiste alcuna variabile di restituzione dell'attività, T, perché
SumPageSizesAsync
non restituisce un valore per T. Il metodo non ha alcuna istruzioneReturn
. Tuttavia, il metodo deve restituireTask
per poter essere un metodo di tipo awaitable. Modificare quindi il tipo di metodo daSub
aFunction
. Il tipo restituito della funzione èTask
.
Nel codice seguente sono illustrate queste modifiche.
Private Async Function SumPageSizesAsync() As Task
La conversione di
SumPageSizes
inSumPageSizesAsync
è completa.
Convertire startButton_Click in un metodo asincrono
Nel gestore eventi modificare il nome del metodo chiamato da
SumPageSizes
inSumPageSizesAsync
, se non è ancora stato fatto.Poiché
SumPageSizesAsync
è un metodo asincrono, modificare il codice nel gestore eventi in modo che attenda il risultato.La chiamata a
SumPageSizesAsync
rispecchia la chiamata aCopyToAsync
inGetURLContentsAsync
. La chiamata restituisceTask
e nonTask(T)
.Come nelle procedure precedenti, è possibile convertire la chiamata tramite una o due istruzioni. Nel codice seguente sono illustrate queste modifiche.
' One-step async call. Await SumPageSizesAsync() ' Two-step async call. Dim sumTask As Task = SumPageSizesAsync() Await sumTask
Per impedire la reentrancy accidentale dell'operazione, aggiungere l'istruzione seguente all'inizio di
startButton_Click
per disabilitare il pulsante Start.' Disable the button until the operation is complete. startButton.IsEnabled = False
È possibile riabilitare il pulsante alla fine del gestore eventi.
' Reenable the button in case you want to run the operation again. startButton.IsEnabled = True
Per altre informazioni sulla reentrancy, vedere Gestione della Reentrancy in Async Apps (Visual Basic).
Aggiungere infine il modificatore
Async
alla dichiarazione, in modo che il gestore eventi possa attendereSumPagSizesAsync
.Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
In genere, i nomi dei gestori eventi non vengono modificati. Il tipo restituito non viene modificato in
Task
perché i gestori eventi devono essere procedureSub
in Visual Basic.La conversione del progetto dall'elaborazione sincrona a quella asincrona è completa.
Eseguire il test della soluzione asincrona
Premere il tasto F5 per eseguire il programma e quindi scegliere il pulsante Start .
Viene visualizzato un output simile all'output della soluzione sincrona. Esistono tuttavia le differenze seguenti:
I risultati non vengono restituiti contemporaneamente, al termine dell'elaborazione. Ad esempio, entrambi i programmi contengono una riga in
startButton_Click
che consente di cancellare la casella di testo. Lo scopo è quello di cancellare il contenuto della casella di testo tra le esecuzioni se si sceglie il pulsante Start per la seconda volta, dopo la visualizzazione di un set di risultati. Nella versione sincrona la casella di testo viene cancellata prima della seconda visualizzazione dei conteggi, ovvero quando vengono completati i download e il thread dell'interfaccia utente è libero di eseguire altre operazioni. Nella versione asincrona, la casella di testo viene cancellata subito dopo aver scelto il pulsante Start.È importante notare che il thread dell'interfaccia utente non è bloccato durante il download. È possibile spostare o ridimensionare la finestra durante il download, il conteggio e la visualizzazione delle risorse Web. Se uno dei siti Web è lento o non risponde, è possibile annullare l'operazione scegliendo il pulsante Chiudi (il simbolo x su sfondo rosso nell'angolo superiore destro).
Sostituire il metodo GetURLContentsAsync con un metodo .NET Framework
.NET Framework offre molti metodi asincroni che è possibile usare. Uno di essi, il metodo HttpClient.GetByteArrayAsync(String), risulta utile in modo specifico per questa procedura dettagliata. È possibile usarlo al posto del metodo
GetURLContentsAsync
creato in una procedura precedente.Il primo passaggio consiste nel creare un oggetto HttpClient nel metodo
SumPageSizesAsync
. Aggiungere la dichiarazione seguente all'inizio del metodo.' 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}
In
SumPageSizesAsync
sostituire la chiamata alGetURLContentsAsync
metodo con una chiamata alHttpClient
metodo .Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
Rimuovere o impostare come commento il metodo
GetURLContentsAsync
precedentemente scritto.Premere il tasto F5 per eseguire il programma e quindi scegliere il pulsante Start .
Il comportamento di questa versione del progetto deve corrispondere al comportamento descritto nella procedura "Per eseguire il test della soluzione asincrona" ma con un intervento ridotto da parte dell'utente.
Esempio
Di seguito è riportato l'esempio completo della soluzione asincrona convertita che usa il metodo GetURLContentsAsync
asincrono. Si noti che è molto simile alla soluzione sincrona originale.
' 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
Il codice seguente contiene l'esempio completo della soluzione che usa il metodo HttpClient
, 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
Vedi anche
- Async Sample: Accessing the Web Walkthrough (C# and Visual Basic) (Esempio asincrono: accesso alla procedura dettagliata Web (C# e Visual Basic)
- Operatore Await
- Async
- Programmazione asincrona con Async e Await (Visual Basic)
- Tipi restituiti asincroni (Visual Basic)
- Programmazione asincrona basata su attività
- Procedura: Estendere la procedura dettagliata asincrona tramite Task.WhenAll (Visual Basic)
- Procedura: Eseguire più richieste Web in parallelo tramite async e await (Visual Basic)