Operador Await (Visual Basic)
Você aplica o Await
operador a um operando em um método assíncrono ou expressão lambda para suspender a execução do método até que a tarefa aguardada seja concluída. A tarefa representa um trabalho contínuo.
O método no qual Await
é usado deve ter um modificador assíncrono . Tal método, definido usando o Async
modificador, e geralmente contendo uma ou mais Await
expressões, é referido como um método assíncrono.
Nota
As Async
palavras-chave e Await
foram introduzidas no Visual Studio 2012. Para obter uma introdução à programação assíncrona, consulte Programação assíncrona com Async e Await.
Normalmente, a tarefa à qual você aplica o Await
operador é o valor de retorno de uma chamada para um método que implementa o padrão assíncrono baseado em tarefas, ou seja, um Task ou um Task<TResult>.
No código a seguir, o HttpClient método GetByteArrayAsync retorna getContentsTask
, a Task(Of Byte())
. A tarefa é uma promessa de produzir a matriz de bytes real quando a operação for concluída. O Await
operador é solicitado a suspender a getContentsTask
execução até SumPageSizesAsync
getContentsTask
que esteja concluída. Enquanto isso, o controle é retornado ao chamador de SumPageSizesAsync
. Quando getContentsTask
terminar, a Await
expressão será avaliada como uma matriz de bytes.
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
Importante
Para obter o exemplo completo, consulte Passo a passo: acessando a Web usando Async e Await. Você pode baixar o exemplo do navegador de exemplo .NET. O código de exemplo está no projeto SerialAsyncExample .
Se Await
for aplicado ao resultado de uma chamada de método que retorna um Task(Of TResult)
, o tipo da Await
expressão é TResult. Se Await
for aplicada ao resultado de uma chamada de método que retorna um Task
, a Await
expressão não retornará um valor. O exemplo a seguir ilustra a diferença.
' 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()
Uma Await
expressão ou instrução não bloqueia o thread no qual está sendo executada. Em vez disso, ele faz com que o compilador inscreva o restante do método assíncrono, após a Await
expressão, como uma continuação na tarefa esperada. Em seguida, o controle retorna ao chamador do método assíncrono. Quando a tarefa é concluída, ela invoca sua continuação e a execução do método assíncrono é retomada de onde parou.
Uma Await
expressão pode ocorrer somente no corpo de um método imediatamente fechado ou expressão lambda marcada por um Async
modificador. O termo Await serve como palavra-chave apenas nesse contexto. Em outros lugares, é interpretado como um identificador. Dentro do Async
método ou expressão lambda, uma Await
expressão não pode ocorrer em uma expressão de consulta, no Catch
bloco ou Finally
de um Try... Pegar... Finalmente, na expressão da variável de controle de loop de um For
ou For Each
loop, ou no corpo de uma instrução SyncLock .
Exceções
A maioria dos métodos assíncronos retorna um Task ou Task<TResult>. As propriedades da tarefa retornada carregam informações sobre seu status e histórico, como se a tarefa foi concluída, se o método assíncrono causou uma exceção ou foi cancelado e qual é o resultado final. O Await
operador acessa essas propriedades.
Se você aguardar um método assíncrono de retorno de tarefa que cause uma exceção, o Await
operador relançará a exceção.
Se você aguardar um método assíncrono de retorno de tarefa que seja cancelado, o Await
operador relançará um OperationCanceledExceptionarquivo .
Uma única tarefa que está em um estado de falha pode refletir várias exceções. Por exemplo, a tarefa pode ser o resultado de uma chamada para Task.WhenAll. Quando você aguarda tal tarefa, a operação await relança apenas uma das exceções. No entanto, você não pode prever qual das exceções será relançada.
Para obter exemplos de tratamento de erros em métodos assíncronos, consulte Tentar... Pegar... Finalmente Declaração.
Exemplo
O exemplo de Windows Forms a seguir ilustra o uso de Await
em um método assíncrono, WaitAsynchronouslyAsync
. Compare o comportamento desse método com o comportamento de WaitSynchronously
. Sem um Await
operador, é executado de forma síncronaAsync
, WaitSynchronously
apesar do uso do modificador em sua definição e uma chamada para Thread.Sleep em seu corpo.
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