Оператор await — асинхронное ожидание завершения задачи.

Оператор await приостанавливает вычисление включающего асинхронного метода до завершения асинхронной операции, представленной его операндом. После завершения асинхронной операции оператор await возвращает результат операции, если таковой имеется. Когда оператор await применяется к операнду, который представляет уже завершенную операцию, он возвращает результат операции немедленно без приостановки включающего метода. Оператор await не блокирует поток, который вычисляет асинхронный метод. Когда оператор await приостанавливает включающий метод async, элемент управления возвращается вызывающему объекту метода.

В следующем примере метод HttpClient.GetByteArrayAsync возвращает экземпляр Task<byte[]>, который представляет асинхронную операцию, создающую массив байтов после завершения. До завершения операции оператор await приостанавливает метод DownloadDocsMainPageAsync. Когда DownloadDocsMainPageAsync приостанавливается, управление возвращается методу Main, который является вызывающим объектом DownloadDocsMainPageAsync. Метод Main выполняется до тех пор, пока ему не потребуется результат асинхронной операции, выполняемой методом DownloadDocsMainPageAsync. Когда GetByteArrayAsync получает все байты, вычисляется остальная часть метода DownloadDocsMainPageAsync. После этого вычисляется остальная часть метода Main.

using System;
using System.Net.Http;
using System.Threading.Tasks;

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.

В предыдущем примере используется асинхронный Main метод . Дополнительные сведения см. в описании оператора await в методе Main.

Примечание

Общие сведения об асинхронном программировании см. в разделе Асинхронное программирование с использованием ключевых слов async и await. Асинхронное программирование async и await следует асинхронной модели, основанной на задачах.

Оператор await можно использовать только в методе, лямбда-выражении или в анонимном методе, изменяемом ключевым словом async. В асинхронном методе нельзя использовать оператор await в теле синхронной функции, внутри блока инструкции lock и в ненадежном контексте.

Операнд оператора await обычно имеет один из следующих типов .NET: Task, Task<TResult>, ValueTask или ValueTask<TResult>. Однако любое ожидаемое выражение может быть операндом оператора await. Дополнительные сведения см. в разделе об ожидаемых выражениях в спецификации языка C#.

Тип выражения await t является TResult, если тип выражения t является Task<TResult> или ValueTask<TResult>. Если тип t является Task или ValueTask, тип await t является void. В обоих случаях, если t вызывает исключение, await t воспроизводит это исключение.

Асинхронные потоки и освобождаемые объекты

Вы можете использовать инструкцию await foreach для работы с асинхронным потоком данных. Дополнительные сведения см. в foreach разделе операторов статьи Операторы итерации .

Инструкция await using используется для работы с асинхронно освобождаемым объектом, то есть с объектом типа, который реализует интерфейс IAsyncDisposable. Дополнительные сведения см. в разделе Использование асинхронных освобождаемых объектов статьи Реализация метода DisposeAsync.

Оператор await в методе Main

МетодMain, который является точкой входа приложения, может возвращать Task или Task<int>, что позволяет ему быть асинхронным, чтобы можно было использовать await оператор в его теле. В более ранних версиях C#, чтобы убедиться, что метод Main ожидает завершения асинхронной операции, можно получить значение свойства Task<TResult>.Result экземпляра Task<TResult>, возвращаемого соответствующим асинхронным методом. Для асинхронных операций, которые не создают значение, можно вызвать метод Task.Wait. См. сведения о том, как выбрать версию языка в описании версий C#.

Спецификация языка C#

Дополнительные сведения см. в разделе об ожидаемых выражениях в спецификации языка C#.

См. также