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 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>.ResultTask<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#.

Consulte também