Operador await - aguardar assincronamente a conclusão de uma tarefa
O await
operador suspende a avaliação do método assíncrono de fechamento até que a operação assíncrona representada por seu operando seja concluída. Quando a operação assíncrona for concluída, o await
operador retornará o resultado da operação, se houver. Quando o await
operador é aplicado ao operando que representa uma operação já concluída, ele retorna o resultado da operação imediatamente sem a suspensão do método de encerramento. O await
operador não bloqueia o thread que avalia o método assíncrono. Quando o operador suspende await
o método assíncrono de delimitação, o controle retorna ao chamador do método.
No exemplo a seguir, o HttpClient.GetByteArrayAsync método retorna a instância, que representa uma operação assíncrona Task<byte[]>
que produz uma matriz de bytes quando ela é concluída. Até que a operação seja concluída, o operador suspende await
o DownloadDocsMainPageAsync
método. Quando DownloadDocsMainPageAsync
é suspenso, o controle é retornado para o Main
método, que é o chamador de DownloadDocsMainPageAsync
. O Main
método é executado até precisar do resultado da operação assíncrona executada DownloadDocsMainPageAsync
pelo método. Quando GetByteArrayAsync obtém todos os bytes, o resto do DownloadDocsMainPageAsync
método é avaliado. Depois disso, o resto do Main
método é avaliado.
public class AwaitOperator
{
public static async Task Main()
{
Task<int> downloading = DownloadDocsMainPageAsync();
Console.WriteLine($"{nameof(Main)}: Launched downloading.");
int bytesLoaded = await downloading;
Console.WriteLine($"{nameof(Main)}: Downloaded {bytesLoaded} bytes.");
}
private static async Task<int> DownloadDocsMainPageAsync()
{
Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: About to start downloading.");
var client = new HttpClient();
byte[] content = await client.GetByteArrayAsync("https://learn.microsoft.com/en-us/");
Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");
return content.Length;
}
}
// Output similar to:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.
O operando de uma await
expressão deve fornecer notificação quando uma tarefa for concluída. Em geral, um delegado é invocado quando a tarefa é concluída, com ou sem êxito. A await
seção da especificação da linguagem C# fornece os detalhes sobre como essas notificações são implementadas.
O exemplo anterior usa o método asyncMain
. Para obter mais informações, consulte o operador await na seção Método principal.
Nota
Para obter uma introdução à programação assíncrona, consulte Programação assíncrona com assíncrono e aguardar. A programação assíncrona com async
e await
segue o padrão assíncrono baseado em tarefas.
Você pode usar o await
operador somente em um método, expressão lambda ou método anônimo modificado pela palavra-chave async . Dentro de um método assíncrono, você não pode usar o await
operador no corpo de uma função local síncrona, dentro do bloco de uma instrução lock e em um contexto inseguro .
O operando do await
operador é geralmente de um dos seguintes tipos .NET: Task, Task<TResult>, ValueTask, ou ValueTask<TResult>. No entanto, qualquer expressão aguardada pode ser o operando do await
operador. Para obter mais informações, consulte a seção Expressões aguardadas da especificação da linguagem C#.
O tipo de expressão await t
é TResult
se o tipo de expressão t
é Task<TResult> ou ValueTask<TResult>. Se o tipo de t
é Task ou ValueTask, o tipo de await t
é void
. Em ambos os casos, se t
lança uma exceção, await t
relança a exceção.
Fluxos assíncronos e descartáveis
Use a instrução para consumir um fluxo assíncrono await foreach
de dados. Para obter mais informações, consulte a foreach
seção de instrução do artigo Instruções de iteração.
Você usa a await using
instrução para trabalhar com um objeto descartável assincronamente, ou seja, um objeto de um tipo que implementa uma IAsyncDisposable interface. Para obter mais informações, consulte a seção Usando assíncrono descartável do artigo Implementar um método DisposeAsync.
await operador no método Main
O Main
método, que é o ponto de entrada do aplicativo, pode retornar Task
ou Task<int>
, permitindo que ele seja assíncrono para que você possa usar o await
operador em seu corpo. Em versões anteriores do C#, para garantir que o Main
método aguarde a conclusão de uma operação assíncrona, você pode recuperar o valor da propriedade da instância que é retornada Task<TResult>.Result Task<TResult> pelo método assíncrono correspondente. Para operações assíncronas que não produzem um valor, você pode chamar o Task.Wait método. Para obter informações sobre como selecionar a versão de idioma, consulte Versão de idioma C#.
Especificação da linguagem C#
Para obter mais informações, consulte a seção Await expressions da especificação da linguagem C#.