다음을 통해 공유


Await 연산자(Visual Basic)

대기 중인 작업이 완료될 때까지 메서드 실행을 일시 중단하려면 비동기 메서드 또는 람다 식의 피연산자에 Await 연산자를 적용합니다. 작업은 진행 중인 작업을 나타냅니다.

Await가 사용된 메서드는 Async 한정자를 포함해야 합니다. Async 한정자를 사용하여 정의하고 일반적으로 하나 이상의 Await 식을 포함하는 이러한 메서드를 비동기 메서드라고 합니다.

참고 항목

AsyncAwait 키워드는 Visual Studio 2012에서 도입되었습니다. 비동기 프로그래밍에 대한 소개는 Async 및 Await를 사용한 비동기 프로그래밍을 참조하세요.

일반적으로 Await 연산자를 적용하는 작업은 작업 기반 비동기 패턴, 즉 Task 또는 Task<TResult>를 구현하는 메서드에 대한 호출로부터 얻은 반환 값입니다.

다음 코드에서 HttpClient 메서드 GetByteArrayAsyncgetContentsTask, Task(Of Byte())를 반환합니다. 이 작업은 작업이 완료될 때 실제 바이트 배열을 생성하기 위한 약속입니다. Await 연산자는 getContentsTask에 적용되어 getContentsTask가 완료될 때까지 SumPageSizesAsync의 실행을 일시 중단합니다. 동시에 컨트롤은 SumPageSizesAsync 호출자에게 반환됩니다. getContentsTask가 완료되면 Await 식이 바이트 배열로 계산됩니다.

Private Async Function SumPageSizesAsync() As Task

    ' To use the HttpClient type in desktop apps, you must include a using directive and add a
    ' reference for the System.Net.Http namespace.
    Dim client As HttpClient = New HttpClient()
    ' . . .
    Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
    Dim urlContents As Byte() = Await getContentsTask

    ' Equivalently, now that you see how it works, you can write the same thing in a single line.
    'Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
    ' . . .
End Function

Important

전체 예제는 연습: Async 및 Await를 사용하여 웹에 액세스를 참조하세요. .NET 샘플 브라우저에서 샘플을 다운로드할 수 있습니다. 예제 코드는 SerialAsyncExample 프로젝트에 있습니다.

AwaitTask(Of TResult)를 반환하는 메서드 호출의 결과에 적용되는 경우, Await식의 형식은 TResult입니다. AwaitTask를 반환하는 메서드 호출의 결과에 적용되는 경우, Await식은 값을 반환하지 않습니다. 다음 예제에서 차이점을 보여 줍니다.

' Await used with a method that returns a Task(Of TResult).
Dim result As TResult = Await AsyncMethodThatReturnsTaskTResult()

' Await used with a method that returns a Task.
Await AsyncMethodThatReturnsTask()

Await 식 또는 문은 식이 실행되고 있는 스레드를 차단하지 않습니다. 대신 Await 식 이후 컴파일러가 대기 중인 작업에서 연속된 작업으로 비동기 메서드의 나머지 부분을 등록하게 됩니다. 그런 다음 컨트롤이 비동기 메서드 호출자에게 반환됩니다. 작업이 완료되면 해당 연속 작업이 호출되고 중단된 비동기 메서드의 실행이 다시 시작됩니다.

Await 식은 Async 수정자로 표시된 람다 식 또는 바로 바깥쪽에 있는 메서드의 본문에만 발생할 수 있습니다. Await라는 용어는 해당 컨텍스트에서만 키워드 역할을 합니다. 다른 컨텍스트에서는 식별자로 해석됩니다. Async 메서드 또는 람다 식 내에서 Await 식은 쿼리 식, Try…Catch…Finally 문Catch 또는 Finally 블록, For 또는 For Each 루프의 루프 제어 변수 식 또는 SyncLock 문의 본문에 올 수 없습니다.

예외

대부분의 비동기 메서드는 Task 또는 Task<TResult>를 반환합니다. 반환된 작업의 속성은 작업의 완료 여부, 비동기 메서드가 예외를 발생시켰는지 취소되었는지 여부 및 최종 결과 등 해당 상태 및 기록에 대한 정보를 전달합니다. Await 연산자는 해당 속성에 액세스합니다.

예외를 발생시키는 작업 반환 비동기 메서드를 기다릴 경우 Await 연산자는 예외를 다시 throw합니다.

취소된 작업 반환 비동기 메서드를 기다릴 경우 Await 연산자는 OperationCanceledException을 다시 throw합니다.

오류가 발생한 상태의 단일 작업에는 여러 예외가 반영될 수 있습니다. 예를 들어 작업은 Task.WhenAll 호출의 결과일 수 있습니다. 이러한 작업을 기다릴 경우 await 작업에서 예외 중 하나만 다시 throw합니다. 그러나 다시 throw되는 예외를 예측할 수 없습니다.

비동기 메서드에서 오류 처리에 대한 예제는 Try...Catch...Finally 문을 참조하세요.

예시

다음 Windows Forms 예제에서는 비동기 메서드 WaitAsynchronouslyAsync에서 Await의 사용을 보여 줍니다. 해당 메서드의 동작을 WaitSynchronously의 동작과 대조합니다. Await 연산자가 없는 경우 WaitSynchronously는 해당 정의에 Async 수정자가 사용되었고 해당 본문에서 Thread.Sleep 호출이 있더라도 동기적으로 실행됩니다.

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ' Call the method that runs asynchronously.
    Dim result As String = Await WaitAsynchronouslyAsync()

    ' Call the method that runs synchronously.
    'Dim result As String = Await WaitSynchronously()

    ' Display the result.
    TextBox1.Text &= result
End Sub

' 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 Function WaitAsynchronouslyAsync() As Task(Of String)
    Await Task.Delay(10000)
    Return "Finished"
End Function

' 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 Function WaitSynchronously() As Task(Of String)
    ' Import System.Threading for the Sleep method.
    Thread.Sleep(10000)
    Return "Finished"
End Function

참고 항목