HOW TO:同時發出多個 Web 要求 (C# 和 Visual Basic)
在非同步方法,,會在建立時,工作開始。 等候 (Visual Basic) 或 等候 (C#) 運算子套用至中的工作會在處理無法繼續的方法,直到工作完成為止。 常用的工作等候,而建立,,如下列範例所示。
Dim result = Await someWebAccessMethodAsync(url)
var 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
// The following line creates and starts the task.
var myTask = someWebAccessMethodAsync(url);
// While the task is running, you can do other work that doesn't depend
// on the results of the task.
// . . . . .
// The application of await suspends the rest of this method until the task is complete.
var result = await myTask;
在開始工作和等待之間,您可以啟動其他工作。 其他工作平行隱含地執行,不過,其他執行緒就不會建立物件。
下列程式啟動三個非同步 Web 下載依它們被呼叫的順序然後等候它們。 請注意,在中,當您執行程式時,工作不按順序一定是完成其建立並等待。 它們開始執行時,會在建立時,,以及一或多項工作可能會完成,在方法到達等待運算式之前。
如需同時啟動多個工作的其他範例,請參閱 HOW TO:使用 Task.WhenAll 擴充逐步解說的內容 (C# 和 Visual Basic)。
若要完成這個專案,您必須在電腦上安裝 Visual Studio 2012 。 如需詳細資訊,請參閱 Microsoft 網站 (英文)。
您可以下載這個範例的程式碼。 開發人員程式碼範例
若要設定專案
若要設定 WPF 應用程式,請完成下列步驟。 您可以在中找到這些步驟的詳細說明 逐步解說:使用 Async 和 Await 存取 Web (C# 和 Visual Basic)。
建立包含文字方塊和按鈕的 WPF 應用程式。 將按鈕 startButton,並將文字方塊 resultsTextBox。
將 System.Net.Http的參考。
在 MainWindow.xaml.vb 或 MainWindow.xaml.cs 中,將 Imports 陳述式或 using 指示詞 System.Net.Http的。
加入程式碼
在 [設計] 視窗,這個檔案是 MainWindow.xaml,在 MainWindow.xaml.vb 或 MainWindow.xaml.cs 中按兩下按鈕建立 startButton_Click 事件處理常式。 如果選取這個選項,選項按鈕,選取 [內容] 視窗的 [所選取項目的事件處理常式] 圖示,然後輸入在 [按一下] 文字方塊的 startButton_Click 。
複製下列程式碼,並將它貼到 startButton_Click 主體在 MainWindow.xaml.vb 或 MainWindow.xaml.cs 中的。
resultsTextBox.Clear() Await CreateMultipleTasksAsync() resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
resultsTextBox.Clear(); await CreateMultipleTasksAsync(); resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
程式碼會呼叫非同步方法, CreateMultipleTasksAsync,驅動應用程式。
將下列方法支援加入至專案:
ProcessURLAsync 使用一個 HttpClient 方法下載網站的內容做為位元組陣列。 支援方法, ProcessURLAsync 然後顯示並傳回陣列的長度。
DisplayResults 顯示位元組數目將位元組陣列中的每個 URL 的。 這會顯示每項工作何時完成下載。
複製下列方法,並在 MainWindow.xaml.vb 或 MainWindow.xaml.cs 中的 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 "http://". Dim displayURL = url.Replace("http://", "") resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes) End Sub
async Task<int> ProcessURLAsync(string url, HttpClient client) { var byteArray = await client.GetByteArrayAsync(url); DisplayResults(url, byteArray); return byteArray.Length; } private void DisplayResults(string url, byte[] content) { // 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. var bytes = content.Length; // Strip off the "http://". var displayURL = url.Replace("http://", ""); resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes); }
最後,定義方法 CreateMultipleTasksAsync,執行下列步驟。
這個方法會宣告 HttpClient 物件,您必須在 ProcessURLAsync的存取方法 GetByteArrayAsync 。
方法會建立並啟動型別 Task<TResult>三項工作, TResult 是整數。 在每項工作完成, DisplayResults 顯示下載內容之工作的 URL 和長度。 因為工作以非同步方式執行,因此出現的順序可能會與其宣告的順序不同。
這個方法等候每項工作的完成。 每個 Await 或 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/en-us/library/hh156528(VS.110).aspx", client) Dim download3 As Task(Of Integer) = ProcessURLAsync("https://msdn.microsoft.com/en-us/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 Task CreateMultipleTasksAsync() { // Declare an HttpClient object, and increase the buffer size. The // default buffer size is 65,536. HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 }; // Create and start the tasks. As each task finishes, DisplayResults // displays its length. Task<int> download1 = ProcessURLAsync("https://msdn.microsoft.com", client); Task<int> download2 = ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client); Task<int> download3 = ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client); // Await each task. int length1 = await download1; int length2 = await download2; int length3 = await download3; int total = length1 + length2 + length3; // Display the total count for the downloaded websites. resultsTextBox.Text += string.Format("\r\n\r\nTotal bytes returned: {0}\r\n", total); }
選取按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/en-us/library/hh156528(VS.110).aspx", client)
Dim download3 As Task(Of Integer) =
ProcessURLAsync("https://msdn.microsoft.com/en-us/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 "http://".
Dim displayURL = url.Replace("http://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Add the following using directive, and add a reference for System.Net.Http.
using System.Net.Http;
namespace AsyncExample_MultipleTasks
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void startButton_Click(object sender, RoutedEventArgs e)
{
resultsTextBox.Clear();
await CreateMultipleTasksAsync();
resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
}
private async Task CreateMultipleTasksAsync()
{
// Declare an HttpClient object, and increase the buffer size. The
// default buffer size is 65,536.
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };
// Create and start the tasks. As each task finishes, DisplayResults
// displays its length.
Task<int> download1 =
ProcessURLAsync("https://msdn.microsoft.com", client);
Task<int> download2 =
ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
Task<int> download3 =
ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);
// Await each task.
int length1 = await download1;
int length2 = await download2;
int length3 = await download3;
int total = length1 + length2 + length3;
// Display the total count for the downloaded websites.
resultsTextBox.Text +=
string.Format("\r\n\r\nTotal bytes returned: {0}\r\n", total);
}
async Task<int> ProcessURLAsync(string url, HttpClient client)
{
var byteArray = await client.GetByteArrayAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}
private void DisplayResults(string url, byte[] content)
{
// 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.
var bytes = content.Length;
// Strip off the "http://".
var displayURL = url.Replace("http://", "");
resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
}
}
}
請參閱
工作
逐步解說:使用 Async 和 Await 存取 Web (C# 和 Visual Basic)
HOW TO:使用 Task.WhenAll 擴充逐步解說的內容 (C# 和 Visual Basic)