Condividi tramite


Procedura: Effettuare più richieste Web in parallelo tramite Async e Await (Visual Basic)

In un metodo asincrono, le attività vengono avviate al momento della creazione. L'operatore Await viene applicato all'attività nel punto nel metodo in cui l'elaborazione non può continuare fino al termine dell'attività. Spesso un'attività è attesa non appena viene creata, come illustrato nell'esempio seguente.

Dim result = Await someWebAccessMethodAsync(url)

Tuttavia, è possibile separare la creazione dell'attività dall'attesa dell'attività se il programma ha un altro lavoro da eseguire che non dipende dal completamento dell'attività.

' 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

Tra l'avvio di un'attività e l'attesa, è possibile avviare altre attività. Le attività aggiuntive vengono eseguite in modo implicito in parallelo, ma non vengono creati thread aggiuntivi.

Il programma seguente avvia tre download Web asincroni e li attende nell'ordine in cui vengono chiamati. Si noti che, quando si esegue il programma, le attività non vengono sempre completate nell'ordine in cui vengono create e attese. Iniziano a essere eseguiti quando vengono creati, e una o più task potrebbero terminare prima che il metodo raggiunga le espressioni di attesa await.

Annotazioni

Per completare questo progetto, è necessario che Nel computer sia installato Visual Studio 2012 o versione successiva e .NET Framework 4.5 o versione successiva.

Per un altro esempio che avvia più attività contemporaneamente, vedere Come estendere la procedura dettagliata asincrona tramite Task.WhenAll (Visual Basic).

È possibile scaricare il codice per questo esempio da Esempi di codice per sviluppatori.

Per configurare il progetto

  1. Per configurare un'applicazione WPF, seguire questa procedura. È possibile trovare istruzioni dettagliate per questi passaggi in Procedura dettagliata: Accesso al Web tramite Async e Await (Visual Basic).You can find detailed instructions for these steps in Walkthrough: Accessing the Web by Using Async and Await (Visual Basic).

    • Creare un'applicazione WPF contenente una casella di testo e un pulsante. Assegnare al pulsante startButtonil nome e assegnare alla casella resultsTextBoxdi testo il nome .

    • Aggiungere un riferimento per System.Net.Http.

    • Nel file MainWindow.xaml.vb aggiungere un'istruzione Imports per System.Net.Http.

Per aggiungere il codice

  1. Nella finestra di progettazione MainWindow.xaml fare doppio clic sul pulsante per creare il startButton_Click gestore eventi in MainWindow.xaml.vb.

  2. Copiare il codice seguente e incollarlo nel corpo di startButton_Click in MainWindow.xaml.vb.

    resultsTextBox.Clear()
    Await CreateMultipleTasksAsync()
    resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    

    Il codice chiama un metodo asincrono, CreateMultipleTasksAsync, che guida l'applicazione.

  3. Aggiungere i metodi di supporto seguenti al progetto:

    • ProcessURLAsync usa un HttpClient metodo per scaricare il contenuto di un sito Web come matrice di byte. Il metodo di supporto visualizza ProcessURLAsync e restituisce la lunghezza della matrice.

    • DisplayResults visualizza il numero di byte nella matrice di byte per ogni URL. Questa visualizzazione viene visualizzata al termine del download di ogni attività.

    Copiare i metodi seguenti e incollarli dopo il startButton_Click gestore eventi 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
    
  4. Infine, definire il metodo CreateMultipleTasksAsync, che esegue i passaggi seguenti.

    • Il metodo dichiara un HttpClient oggetto, necessario per accedere al metodo GetByteArrayAsync in ProcessURLAsync.

    • Il metodo crea e avvia tre attività di tipo Task<TResult>, dove TResult è un numero intero. Al termine di ogni attività, DisplayResults visualizza l'URL dell'attività e la lunghezza del contenuto scaricato. Poiché le attività vengono eseguite in modo asincrono, l'ordine in cui i risultati vengono visualizzati potrebbe differire dall'ordine in cui sono state dichiarate.

    • Il metodo attende il completamento di ogni attività. Ogni Await operatore sospende l'esecuzione di CreateMultipleTasksAsync fino al termine dell'attività attesa. L'operatore recupera anche il valore restituito dalla chiamata a ProcessURLAsync da ogni attività completata.

    • Una volta completate le attività e recuperati i valori interi, il metodo somma le lunghezze dei siti Web e visualizza il risultato.

    Copiare il metodo seguente e incollarlo nella soluzione.

    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
    
  5. Scegliere il tasto F5 per eseguire il programma e quindi scegliere il pulsante Start .

    Eseguire il programma più volte per verificare che le tre attività non vengano sempre completate nello stesso ordine e che l'ordine in cui terminano non sia necessariamente l'ordine in cui vengono create e attese.

Esempio

Il codice seguente contiene l'esempio completo.

' 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

Vedere anche