await (C# 參考)
await 運算子套用至非同步方法的工作暫停執行方法,直到等候的工作完成。 工作代表持續性的工作。
await 使用的非同步方法必須以 非同步 關鍵字修改。 這種方法,來定義 async 修飾詞和通常包含一或多個 await 運算式,稱為 非同步方法。
![]() |
---|
async 與 await 關鍵字在 Visual Studio 2012 中引入。如需在該版本的新功能的詳細資訊,請參閱 Visual Studio 2012 的新功能。 如需非同步程式設計的簡介,請參閱 使用 Async 和 Await 設計非同步程式 (C# 和 Visual Basic)。 |
await 運算子通常套用的工作是從呼叫的傳回值為實作 以工作的非同步模式的方法。 範例型別 Task 或 Task<TResult>的值。
在下列程式碼中, HttpClient 方法 GetByteArrayAsync 傳回 Task<byte[]>,否則為 getContentsTask。 當工作完成時,工作是承諾產生實際位元組陣列。 await 運算子在 SumPageSizesAsync 套用至 getContentsTask 暫停執行,直到 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 運算式的型別為參數。 如果 await 套用至傳回 Task方法呼叫的結果,則 await 運算式的型別是空的。 下列範例說明差異。
// 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 運算式或匿名方法的主體可能只會發生。 這個詞彙 等候 為只關鍵字在該內容。 在其他位置,則會將它解譯為識別項。 在方法、Lambda 運算式或匿名方法內, await 運算式不能出現在同步函式主體,在查詢運算式中,在 例外狀況處理陳述式的 catch 或 finally 區塊,在 lock 陳述式的區塊,或在 不安全 內容。
例外狀況
大部分的非同步方法傳回 Task 或 Task<TResult>。 傳回的工作屬性傳用相對於其狀態和記錄的資訊,例如工作是否完成,非同步方法是否會造成例外狀況或被取消,,以及最後結果是。 await 運算子存取這些屬性。
如果等候造成例外狀況的工作傳回的非同步方法, await 運算子會重新擲回例外狀況。
如果您已取消的工作傳回的非同步方法, await 運算子擲回 OperationCanceledException。
在錯誤狀態的單一工作可以反映多個例外狀況。 例如,工作可能是呼叫 Task.WhenAll。 當您等候這類工作,例外狀況的等候作業擲回只有一個。 不過,您無法預測的例外狀況。
以在非同步方法的錯誤處理的範例,請參閱 try-catch (C# 參考)。
範例
下列 Windows Form 範例示範在非同步方法的 await ,否則為 WaitAsynchronouslyAsync。 比對該方法的行為和 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)