共用方式為


如何:使用 Async 和 Await 平行提出多個 Web 要求 (Visual Basic)

在異步方法中,任務會在建立時啟動。 Await 運算子應用於方法中的某一點,此時工作未完成之前,無法繼續處理。 任務通常在創建後立即等待,如下列範例所示。

Dim result = Await someWebAccessMethodAsync(url)

不過,如果您的程式有其他不依賴於該工作完成的任務需要完成,您可以將建立工作與等待工作分開來執行。

' 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

在啟動和等待一項任務之間,您可以開始其他任務。 其他工作會以平行方式隱含執行,但不會建立其他線程。

下列程式會啟動三個異步 Web 下載,然後依呼叫的順序等候它們。 請注意,當您執行程式時,工作不一定會依建立和等候的順序完成。 它們會在建立的瞬間開始執行,而且有一個或多個工作可能會在方法到達 await 運算式之前完成。

備註

若要完成此專案,您必須在計算機上安裝Visual Studio 2012或更高版本和 .NET Framework 4.5 或更高版本。

如需同時啟動多個工作的另一個範例,請參閱 How to: Extend the Async Walkthrough by Using Task.WhenAll (Visual Basic)

您可以從 開發人員程式代碼範例下載此範例的程式代碼。

設定專案

  1. 若要設定 WPF 應用程式,請完成下列步驟。 您可以在 逐步指南:使用 Async 和 Await 存取 Web (Visual Basic) 中找到這些步驟的詳細指示。

    • 建立包含文字框和按鈕的 WPF 應用程式。 將按鍵 startButton命名為 ,並將文字框 resultsTextBox命名為 。

    • 加入 System.Net.Http 的參考。

    • 在 MainWindow.xaml.vb 檔案中,為 Imports 新增一個 System.Net.Http 語句。

新增代碼

  1. 在設計視窗中,MainWindow.xaml 按兩下按鈕,以在 MainWindow.xaml.vb 中建立 startButton_Click 事件處理程式。

  2. 複製下列程序代碼,並將它貼到 MainWindow.xaml.vb 的主體 startButton_Click 中。

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

    程式代碼會呼叫異步方法, CreateMultipleTasksAsync以驅動應用程式。

  3. 將下列支援方法新增至專案:

    • ProcessURLAsync使用HttpClient方法,將網站的內容下載為位元組陣列。 支援函數接著 ProcessURLAsync 會顯示並傳回陣列的長度。

    • DisplayResults 會顯示每個 URL 位元組陣列中的位元組數目。 此顯示會顯示每個工作完成下載的時機。

    複製下列方法,並將其貼到 MainWindow.xaml.vb 中的事件處理程序之後 startButton_Click

    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. 最後,定義方法 CreateMultipleTasksAsync,其會執行下列步驟。

    • 方法會宣告HttpClient物件,您需要在GetByteArrayAsync中存取方法ProcessURLAsync

    • 方法會建立並啟動 類型 Task<TResult>為的三個工作,其中 TResult 是整數。 當每個工作完成時, DisplayResults 會顯示工作的URL和所下載內容的長度。 由於工作會以異步方式執行,因此結果出現的順序可能與宣告的順序不同。

    • 方法會等候每項工作的完成。 每個 Await 運算子都會暫停執行 CreateMultipleTasksAsync ,直到等候的工作完成為止。 運算子也會從每個已完成工作的呼叫 ProcessURLAsync 擷取傳回值。

    • 當工作完成且已擷取整數值時,方法會加總網站長度並顯示結果。

    複製下列方法,並將它貼到您的解決方案中。

    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. 選擇 F5 鍵以執行程式,然後選擇 [ 開始 ] 按鈕。

    執行程式數次,以確認這三個工作不一定以相同順序完成,而且完成的順序不一定是建立和等候的順序。

範例

下列程式代碼包含完整的範例。

' 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

另請參閱