Await 運算子 (Visual Basic)
您在非同步方法或 Lambda 運算式的運算域中使用 Await 運算子以擱置方法的執行,直到等候的工作完成。 工作代表進行中的工作。
Await 所使用的方法必須有 Async 修飾詞。 這種方法,透過使用 Async 修飾詞來定義和通常包含一或多個 Await 運算式,稱為「非同步方法」(async method)。
注意事項 |
---|
Async 與 Await 關鍵字在 Visual Studio 2012 中引入。如需非同步程式設計的簡介,請參閱使用 Async 和 Await 設計非同步程式 (C# 和 Visual Basic)。 |
Await 運算子套用的工作通常是實作以工作為基礎的非同步模式的方法呼叫之傳回值,也就是說是 Task 或是 Task。
在下列程式碼中,HttpClient 方法 GetByteArrayAsync 會傳回 getContentsTask、Task(Of Byte())。 這個工作保證作業完成時,一定會產生實際位元組陣列。 Await 運算子套用至 getContentsTask 以暫停 SumPageSizesAsync 中的執行,直到 getContentsTask 完成。 同時,控制項會返回 SumPageSizesAsync 的呼叫端。 當 getContentsTask 完成時,Await 運算式評估為位元組陣列。
Private Async Function SumPageSizesAsync() As Task
' To use the HttpClient type in desktop apps, you must include a using directive and add a
' reference for the System.Net.Http namespace.
Dim client As HttpClient = New HttpClient()
' . . .
Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
Dim urlContents As Byte() = Await getContentsTask
' Equivalently, now that you see how it works, you can write the same thing in a single line.
'Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
' . . .
End Function
重要
如需完整的範例,請參閱 逐步解說:使用 Async 和 Await 存取 Web (C# 和 Visual Basic)。您可以從Microsoft 網站上的開發人員程式碼範例下載範例。這個範例是在 AsyncWalkthrough_HttpClient 專案中。
如果將 Await 套用至傳回 Task(Of TResult) 之方法呼叫的結果,則 Await 運算式的類型為 TResult。 如果 Await 套用至傳回 Task 之方法呼叫的結果,則 Await 運算式不會傳回值。 下列範例說明差異。
' Await used with a method that returns a Task(Of TResult).
Dim result As TResult = Await AsyncMethodThatReturnsTaskTResult()
' Await used with a method that returns a Task.
Await AsyncMethodThatReturnsTask()
Await 運算式或陳述式不會封鎖其執行所在的執行緒。 相反地,它會造成編譯器將在運算式之後其餘的非同步方法(在 Await 運算式之後的)註冊為被等候工作的接續。 控制權會返回非同步方法的呼叫端。 當工作完成時,它會叫用其接續,而且非同步方法的執行會從先前暫停的地方繼續。
Await 運算式可能只會在 Async 修飾詞所標示之立即封入方法或Lambda 運算式的主體中發生。 「等候」(await) 這個詞彙只在該內容中做為關鍵字。 在其他位置,則會將它解譯為識別碼。 在非同步方法或 Lambda 運算式中, Await 運算式不能出現在查詢運算式、 Try…Catch…Finally 陳述式中的 catch 或 finally 區塊、 For 或 For Each 迴圈中的迴圈控制變數運算式中、或在 SyncLock 陳述式的主體中。
例外狀況
大部分非同步方法會傳回 Task 或 Task。 傳回的工作屬性含有其狀態和記錄的資訊,例如工作是否完成,非同步方法是否造成例外狀況或被取消,以及最後結果。 Await 運算子存取這些屬性。
如果等候造成例外狀況的工作傳回非同步方法,則 Await 運算子會重新擲回例外狀況。
如果您等候已取消之工作傳回非同步方法,則 Await 運算子會重新擲回 OperationCanceledException。
處於錯誤狀態的單一工作可能反映多個例外狀況。例如,工作可能是呼叫 Task.WhenAll 的結果。 當您等候這類工作時,等候作業只擲回其中一個例外狀況。 不過,您無法預測會重新擲回哪一個例外狀況。
如需非同步方法錯誤處理的範例,請參閱 Try...Catch...Finally 陳述式 (Visual Basic)。
範例
下列 Windows Form 範例示範在非同步方法 WaitAsynchronouslyAsync 中 Await 的用法。 將該方法的表現方式對照 WaitSynchronously 的表現方式。 若WaitSynchronously 沒有 Await 運算子,儘管其定義使用 Async 修飾詞並在主體呼叫 Thread.Sleep,它仍會同步執行。
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Call the method that runs asynchronously.
Dim result As String = Await WaitAsynchronouslyAsync()
' Call the method that runs synchronously.
'Dim result As String = Await WaitSynchronously()
' Display the result.
TextBox1.Text &= result
End Sub
' 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 Function WaitAsynchronouslyAsync() As Task(Of String)
Await Task.Delay(10000)
Return "Finished"
End Function
' 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 Function WaitSynchronously() As Task(Of String)
' Import System.Threading for the Sleep method.
Thread.Sleep(10000)
Return "Finished"
End Function
請參閱
工作
逐步解說:使用 Async 和 Await 存取 Web (C# 和 Visual Basic)