await (C# 參考)
await 運算子套用至非同步方法的工作,以暫停執行方法,直到等候的工作完成。 工作代表進行中的工作。
await 使用的非同步方法必須以 async 關鍵字修改。 這種方法,透過使用 async 修飾詞來定義和通常包含一或多個 await 運算式,稱為「非同步方法」(async method)。
注意事項 |
---|
async 與 await 關鍵字在 Visual Studio 2012 中引入。如需非同步程式設計的簡介,請參閱使用 Async 和 Await 設計非同步程式 (C# 和 Visual Basic)。 |
await 運算子套用的工作通常是實作以工作為基礎的非同步模式的方法呼叫的傳回值。 範例包含屬於類型 Task 或 Task 的值。
在下列程式碼中,HttpClient 方法 GetByteArrayAsync 會傳回 Task<byte[]>、getContentsTask。 工作完成時,一定會產生實際位元組陣列。 await 運算子套用至 getContentsTask 以暫停 SumPageSizesAsync 中的執行,直到 getContentsTask 完成。 同時,控制項會返回 SumPageSizesAsync 的呼叫端。 當 getContentsTask 完成時,await 運算式評估為位元組陣列。
private async Task SumPageSizesAsync()
{
// To use the HttpClient type in desktop apps, you must include a using directive and add a
// reference for the System.Net.Http namespace.
HttpClient client = new HttpClient();
// . . .
Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
byte[] urlContents = await getContentsTask;
// Equivalently, now that you see how it works, you can write the same thing in a single line.
//byte[] urlContents = await client.GetByteArrayAsync(url);
// . . .
}
重要
如需完整的範例,請參閱 逐步解說:使用 Async 和 Await 存取 Web (C# 和 Visual Basic)。您可以從Microsoft 網站上的開發人員程式碼範例下載範例。這個範例是在 AsyncWalkthrough_HttpClient 專案中。
如上一個範例所示,如果將 await 套用至傳回 Task<TResult> 之方法呼叫的結果,則 await 運算式的類型為 TResult。 如果將 await 套用至傳回 Task 之方法呼叫的結果,則 await 運算式的類型為 void。 下列範例說明差異。
// Keyword await used with a method that returns a Task<TResult>.
TResult result = await AsyncMethodThatReturnsTaskTResult();
// Keyword await used with a method that returns a Task.
await AsyncMethodThatReturnsTask();
await 運算式不會封鎖其執行所在的執行緒。 相反地,它會造成編譯器將其餘的非同步方法註冊為被等候工作的接續。 控制權會返回非同步方法的呼叫端。 當工作完成時,它會叫用其接續,而且非同步方法的執行會從先前暫停的地方繼續。
await 運算式可能只會在 async 修飾詞所標示之立即封入方法、Lambda 運算式或匿名方法的主體中發生。 「等候」(await) 這個詞彙只在該內容中做為關鍵字。 在其他位置,則會將它解譯為識別碼。 在方法、Lambda 運算式或匿名方法中, await 運算式不能出現在同步函式主體、查詢運算式、例外狀況處理陳述式的 catch 或 finally 區塊, lock 陳述式的區塊,或 不安全 內容中。
例外狀況
大部分非同步方法會傳回 Task 或 Task。 傳回的工作屬性含有其狀態和記錄的資訊,例如工作是否完成,非同步方法是否造成例外狀況或被取消,以及最後結果。 await 運算子存取這些屬性。
如果等候造成例外狀況的工作傳回非同步方法,則 await 運算子會重新擲回例外狀況。
如果您等候已取消的工作傳回非同步方法,則 await 運算子會重新擲回 OperationCanceledException。
處於錯誤狀態的單一工作可能反映多個例外狀況。 例如,工作可能是呼叫 Task.WhenAll 的結果。 當您等候這類工作時,等候作業只擲回其中一個例外狀況。 不過,您無法預測會重新擲回哪一個例外狀況。
如需非同步方法錯誤處理的範例,請參閱 try-catch (C# 參考)。
範例
下列 Windows Form 範例示範在非同步方法 WaitAsynchronouslyAsync 中 await 的用法。 將該方法的表現方式對照 WaitSynchronously 的表現方式。 若工作未套用 await 運算子,WaitSynchronously 會同步執行,但在其定義使用 async 修飾詞並在主體使用 Thread.Sleep呼叫 。
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
請參閱
工作
逐步解說:使用 Async 和 Await 存取 Web (C# 和 Visual Basic)