await 연산자 - 작업이 완료되도록 비동기적으로 대기

await 연산자는 피연산자가 나타내는 비동기 작업이 완료될 때까지 바깥쪽 비동기 메서드의 평가를 일시 중단합니다. 비동기 작업이 완료되면 await 연산자는 작업 결과를 반환합니다(있는 경우). 이미 완료된 작업을 나타내는 피연산자에 await 연산자가 적용되면 바깥쪽 메서드를 일시 중단하지 않고 작업 결과를 즉시 반환합니다. await 연산자는 비동기 메서드를 평가하는 스레드를 차단하지 않습니다. await 연산자가 바깥쪽 비동기 메서드를 일시 중단하면 제어가 메서드 호출자에게 반환됩니다.

다음 예제에서 HttpClient.GetByteArrayAsync 메서드는 완료 시 바이트 배열을 생성하는 비동기 작업을 나타내는 Task<byte[]> 인스턴스를 반환합니다. 작업이 완료될 때까지 await 연산자는 DownloadDocsMainPageAsync 메서드를 일시 중단합니다. DownloadDocsMainPageAsync가 일시 중단되면 제어는 DownloadDocsMainPageAsync의 호출자인 Main 메서드에 반환됩니다. Main 메서드는 DownloadDocsMainPageAsync 메서드가 수행한 비동기 작업의 결과가 필요할 때까지 실행됩니다. GetByteArrayAsync가 모든 바이트를 가져오면 나머지 DownloadDocsMainPageAsync 메서드가 평가됩니다. 그 후에는 나머지 Main 메서드가 평가됩니다.

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.

await 식의 피연산자는 작업 완료 시 알림을 제공해야 합니다. 일반적으로 작업이 성공적으로 또는 실패로 완료되면 대리자가 호출됩니다. C# 언어 사양의 await 섹션에서는 이러한 알림이 구현되는 방법에 대한 세부 정보를 제공합니다.

앞의 예제에서는 비동기 Main 메서드를 사용합니다. 자세한 내용은 Main 메서드 섹션의 await 연산자를 참조하세요.

참고

비동기 프로그래밍에 대한 소개는 async 및 await를 사용한 비동기 프로그래밍을 참조하세요. asyncawait를 사용하는 비동기 프로그래밍은 작업 기반 비동기 패턴을 따릅니다.

async 키워드로 수정된 메서드, 람다 식 또는 무명 메서드에는 await 연산자만 사용할 수 있습니다. 비동기 메서드 내의 동기 함수 본문, lock 문 블록 및 unsafe 컨텍스트에서는 await 연산자를 사용할 수 없습니다.

await 연산자의 피연산자는 일반적으로 .NET 형식인 Task, Task<TResult>, ValueTask 또는 ValueTask<TResult> 중 하나에 해당합니다. 그러나 대기 가능한 모든 식은 await 연산자의 피연산자일 수 있습니다. 자세한 내용은 C# 언어 사양대기 가능 식 섹션을 참조하세요.

t 식의 형식이 Task<TResult> 또는 ValueTask<TResult>이면 await t 식의 형식은 TResult입니다. t 형식이 Task 또는 ValueTask이면 await t 형식은 void입니다. 두 경우 모두 t가 예외를 throw하면 await t는 예외를 다시 throw합니다.

비동기 스트림 및 삭제 가능한 항목

await foreach 문을 사용하여 비동기 데이터 스트림을 사용합니다. 자세한 내용은 반복 문 문서의 foreach 섹션을 참조하세요.

await using 문을 사용하여 삭제 가능한 개체, 즉 IAsyncDisposable 인터페이스를 구현하는 형식의 개체를 비동기적으로 사용합니다. 자세한 내용은 DisposeAsync 메서드 구현 문서의 삭제 가능한 비동기 항목 사용 섹션을 참조하세요.

Main 메서드의 await 연산자

애플리케이션 진입점인 Main 메서드Task 또는 Task<int>를 반환하여 해당 본문에서 await 연산자를 사용할 수 있습니다. 이전 C# 버전에서는 Main 메서드가 비동기 작업이 완료될 때까지 대기하는지 확인하기 위해 해당 비동기 메서드에서 반환되는 Task<TResult> 인스턴스의 Task<TResult>.Result 속성 값을 검색할 수 있습니다. 값을 생성하지 않는 비동기 작업의 경우 Task.Wait 메서드를 호출할 수 있습니다. 언어 버전을 선택하는 방법에 대한 자세한 내용은 C# 언어 버전을 참조하세요.

C# 언어 사양

자세한 내용은 C# 언어 사양Await 식 섹션을 참조하세요.

참고 항목