await (Referência de C#)

O operador de await é aplicado a uma tarefa em um método assíncrono para suspender a execução do método até que a tarefa esperada terminar. A tarefa representa um trabalho em andamento.

O método assíncrono em que await é usado deve ser modificado pela palavra-chave async . Esse método, definido usando o modificador de async , e geralmente contendo uma ou mais expressões de await , é conhecido como um método assíncrono.

Dica

As palavras-chave de async e de await foram introduzidas no Visual Studio 2012.Para uma introdução de programação async, consulte Programação assíncrona com Async e Await (C# e Visual Basic).

A tarefa à qual o operador de await é aplicada é normalmente o valor de retorno de uma chamada para um método que implementa o Padrão assíncrono baseado em tarefa. Os exemplos incluem valores do tipo Task ou Task.

No código a seguir, o método HttpClient GetByteArrayAsync retorna uma Task<byte[]>, getContentsTask. A tarefa é uma promessa de gerar a matriz de bytes atual quando a tarefa for concluída. O operador de await é aplicado a getContentsTask para suspender a execução em SumPageSizesAsync até que getContentsTask seja concluída. Enquanto isso, o controle é retornado ao chamador de SumPageSizesAsync. Quando getContentsTask termina, a expressão await é avaliada como uma matriz de bytes.

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);
    // . . .
}

Importante

Para um exemplo completo, consulte Instruções passo a passo: acessando a Web e usando Async e Await (C# e Visual Basic).Você pode baixar o exemplo de Exemplos de código do desenvolvedor no site da Microsoft.O exemplo está no projeto de AsyncWalkthrough_HttpClient.

Conforme mostrado no exemplo anterior, se await é aplicado ao resultado de uma chamada de método que retorna Task<TResult>, o tipo da expressão await é TResult. Se await é aplicado ao resultado de uma chamada de método que retorna Task, o tipo da expressão await é void. O exemplo a seguir ilustra a diferença.

// 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();

Uma expressão await não bloqueia o thread no qual está executando. Em vez disso, faz com que o compilador assine o resto do método assíncrono como uma continuação da tarefa esperada. Então, o controle retorna para o chamador do método async. Quando a tarefa termina, ela chama sua continuação, e a execução do método de async continua onde parou.

Uma expressão await pode ocorrer apenas no corpo de um método imediatamente delimitador, expressão lambda ou método anônimo que é marcado por um modificador de async. O termo await serve como uma palavra-chave somente nesse contexto. Em outro lugar, é interpretado como um identificador. No método, a expressão lambda, ou o método anônimo, uma expressão de await não pode ocorrer no corpo de uma função síncrona, em uma expressão de consulta, no bloco de catch ou de finally de uma instrução de manipulação de exceção, no bloco de instrução de bloqueio, ou em um contexto não seguro .

Exceções

A maioria dos métodos assíncronos retornam Task ou Task. As propriedades da tarefa retornada transportam informações sobre seus status e histórico como, por exemplo, se a tarefa está concluída, se o método de async causou uma exceção ou foi cancelado, e o qual é o resultado final. O operador de await acessa essas propriedades.

Se você aguardar um método assíncrono de retorno de tarefa que cause uma exceção, o operador await relançará a exceção.

Se você aguardar um método assíncrono de retorno de tarefa que seja cancelado, o operador await relançará uma OperationCanceledException.

Uma única tarefa que apresentar defeito pode refletir em diversas exceções. Por exemplo, a tarefa pode ser resultado de uma chamada para Task.WhenAll. Quando você espera uma tarefa, a operação de espera relança apenas uma das exceções. No entanto, não é possível prever qual das exceções será lançada novamente.

Para exemplos de tratamento de erro em métodos assíncronos, consulte try-catch (Referência de C#).

Exemplo

O seguinte exemplo do Windows Forms ilustra o uso de await em um método assíncrono, WaitAsynchronouslyAsync. Destaque o comportamento do método com o comportamento de WaitSynchronously. Sem um operador de await aplicado a uma tarefa, WaitSynchronously executa de modo síncrono independentemente do modificador de async em sua definição e em uma chamada a Thread.Sleep no corpo.

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";
}

Consulte também

Tarefas

Instruções passo a passo: acessando a Web e usando Async e Await (C# e Visual Basic)

Referência

async (Referência de C#)

Conceitos

Programação assíncrona com Async e Await (C# e Visual Basic)