Await — Operator (Visual Basic)
Operator jest Await
stosowany do operandu w metodzie asynchronicznej lub wyrażeniu lambda w celu wstrzymania wykonywania metody do momentu zakończenia oczekiwanego zadania. Zadanie reprezentuje bieżącą pracę.
Metoda, w której Await
jest używana, musi mieć modyfikator Async . Taka metoda, zdefiniowana przy użyciu Async
modyfikatora, i zwykle zawierająca co najmniej jedno Await
wyrażenie, jest określana jako metoda asynchronizatora.
Uwaga
Słowa Async
kluczowe i Await
zostały wprowadzone w programie Visual Studio 2012. Aby zapoznać się z wprowadzeniem do programowania asynchronicznego, zobacz Asynchroniczne programowanie z funkcją Async i Await.
Zazwyczaj zadanie, do którego stosuje Await
się operator, jest wartością zwracaną z wywołania metody, która implementuje wzorzec asynchroniczny oparty na zadaniach, czyli element Task lub Task<TResult>.
W poniższym kodzie HttpClient metoda zwraca getContentsTask
metodę GetByteArrayAsync , a Task(Of Byte())
. Zadanie jest obietnicą utworzenia rzeczywistej tablicy bajtów po zakończeniu operacji. Operator jest stosowany do wstrzymania Await
wykonywania do SumPageSizesAsync
momentu getContentsTask
ukończenia.getContentsTask
W międzyczasie kontrolka jest zwracana do obiektu wywołującego .SumPageSizesAsync
Po getContentsTask
zakończeniu Await
wyrażenie daje w wyniku tablicę bajtów.
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
Ważne
Aby zapoznać się z pełnym przykładem, zobacz Przewodnik: uzyskiwanie dostępu do sieci Web przy użyciu Async i Await. Przykład można pobrać z przykładowej przeglądarki .NET. Przykładowy kod znajduje się w projekcie SerialAsyncExample .
Jeśli Await
jest stosowany do wyniku wywołania metody zwracającej Task(Of TResult)
wartość , typ Await
wyrażenia to TResult. Jeśli Await
jest stosowany do wyniku wywołania metody zwracającej Task
wartość , Await
wyrażenie nie zwraca wartości. Poniższy przykład ilustruje różnicę.
' 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()
Wyrażenie Await
lub instrukcja nie blokuje wątku, na którym jest wykonywany. Zamiast tego kompilator tworzy konto pozostałej części metody asynchronicznej po wyrażeniu Await
jako kontynuacji oczekiwanego zadania. Następnie kontrolka powraca do obiektu wywołującego metody asynchronicznej. Po zakończeniu zadania wywołuje kontynuację, a wykonanie metody asynchronicznej jest wznawiane w miejscu, w którym zostało przerwane.
Wyrażenie Await
może wystąpić tylko w treści natychmiast otaczającej metody lub wyrażenia lambda oznaczonego Async
przez modyfikator. Termin Await służy jako słowo kluczowe tylko w tym kontekście. Gdzie indziej, jest interpretowany jako identyfikator. Async
W ramach metody lub wyrażenia Await
lambda wyrażenie nie może wystąpić w wyrażeniu zapytania, w Catch
bloku lub Finally
w try... Złapać... Na koniec instrukcja w wyrażeniu For
zmiennej sterującej pętli lub For Each
w treści instrukcji SyncLock.
Wyjątki
Większość metod asynchronicznych zwraca wartość Task lub Task<TResult>. Właściwości zwróconego zadania zawierają informacje o jego stanie i historii, takie jak to, czy zadanie zostało ukończone, czy metoda asynchronizna spowodowała wyjątek, czy została anulowana, oraz jaki jest wynik końcowy. Operator Await
uzyskuje dostęp do tych właściwości.
Jeśli oczekujesz na metodę asynchroniową zwracającą zadanie, która powoduje wyjątek, Await
operator ponownie wywróci wyjątek.
Jeśli oczekujesz na metodę asynchroniową zwracającą zadanie, która zostanie anulowana, Await
operator ponownie wniesie element OperationCanceledException.
Pojedyncze zadanie, które jest w stanie uszkodzonym, może odzwierciedlać wiele wyjątków. Na przykład zadanie może być wynikiem wywołania metody Task.WhenAll. Gdy oczekujesz na takie zadanie, operacja await ponownie przeroczy tylko jeden z wyjątków. Nie można jednak przewidzieć, który z wyjątków zostanie ponownie przerzucony.
Przykłady obsługi błędów w metodach asynchronicznych można znaleźć w temacie Try... Złapać... Finally, instrukcja.
Przykład
Poniższy przykład formularzy systemu Windows ilustruje użycie metody Await
w metodzie asynchronicznej : WaitAsynchronouslyAsync
. Kontrastuje zachowanie tej metody z zachowaniem WaitSynchronously
klasy . Await
Bez operatora działa WaitSynchronously
synchronicznie pomimo użycia Async
modyfikatora w jego definicji i wywołania metody Thread.Sleep w jego treści.
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