다음을 통해 공유


비동기 반환 형식(Visual Basic)

비동기 메서드에는 Task<TResult>, Task, 및 void의 세 가지 가능한 반환 형식이 있습니다. Visual Basic에서 void 반환 형식은 하위 프로시저로 작성됩니다. 비동기 메서드에 대한 자세한 내용은 Async 및 Await를 사용한 비동기 프로그래밍(Visual Basic)을 참조하세요.

각 반환 형식은 다음 섹션 중 하나에서 검사되며 항목의 끝에 있는 세 가지 형식을 모두 사용하는 전체 예제를 찾을 수 있습니다.

비고

예제를 실행하려면 Visual Studio 2012 이상과 .NET Framework 4.5 이상이 컴퓨터에 설치되어 있어야 합니다.

Task(T) 반환 형식

Task<TResult> 반환 형식은 피연산자의 형식이 있는 TResult 문을 포함하는 비동기 메서드에 사용됩니다.

다음 예제 TaskOfT_MethodAsync 에서 비동기 메서드는 정수 값을 반환하는 return 문을 포함합니다. 따라서 메서드 선언은 반환 형식 Task(Of Integer)을 지정해야 합니다.

' TASK(OF T) EXAMPLE
Async Function TaskOfT_MethodAsync() As Task(Of Integer)

    ' The body of an async method is expected to contain an awaited
    ' asynchronous call.
    ' Task.FromResult is a placeholder for actual work that returns a string.
    Dim today As String = Await Task.FromResult(Of String)(DateTime.Now.DayOfWeek.ToString())

    ' The method then can process the result in some way.
    Dim leisureHours As Integer
    If today.First() = "S" Then
        leisureHours = 16
    Else
        leisureHours = 5
    End If

    ' Because the return statement specifies an operand of type Integer, the
    ' method must have a return type of Task(Of Integer).
    Return leisureHours
End Function

TaskOfT_MethodAsync await 식 안에서 호출될 때, await 식은 leisureHours로부터 반환된 작업에 저장된 정수 값(TaskOfT_MethodAsync의 값)을 검색합니다. await 식에 대한 자세한 내용은 Await 연산자를 참조하세요.

다음 코드는 메서드 TaskOfT_MethodAsync를 호출하고 대기합니다. 결과는 변수에 result1 할당됩니다.

' Call and await the Task(Of T)-returning async method in the same statement.
Dim result1 As Integer = Await TaskOfT_MethodAsync()

다음 코드와 같이 호출 TaskOfT_MethodAsync 을 애플리케이션 Await에서 분리하여 이 작업을 더 잘 이해할 수 있습니다. 메서드 TaskOfT_MethodAsync 에 대한 호출이 즉시 대기되지 않는 경우, 메서드 선언에 근거하여 예상할 수 있는 Task(Of Integer) 를 반환합니다. 이 작업은 예제의 변수에 integerTask 할당됩니다. integerTaskTask<TResult>이므로 Result 유형의 TResult 속성을 포함합니다. 이 경우 TResult는 정수 형식을 나타냅니다. AwaitintegerTask에 적용되면 await 식은 ResultintegerTask 속성의 내용으로 평가됩니다. 값이 변수에 result2 할당됩니다.

경고

Result 속성은 차단 속성입니다. 작업이 완료되기 전에 액세스하려고 하면 작업이 완료되고 값을 사용할 수 있게 될 때까지 현재 활성 상태인 스레드가 차단됩니다. 대부분의 경우 속성에 직접 액세스하는 대신 사용하여 Await 값에 액세스해야 합니다.

' Call and await in separate statements.
Dim integerTask As Task(Of Integer) = TaskOfT_MethodAsync()

' You can do other work that does not rely on resultTask before awaiting.
textBox1.Text &= "Application can continue working while the Task(Of T) runs. . . . " & vbCrLf

Dim result2 As Integer = Await integerTask

다음 코드에서 출력 지시문은 result1 변수가, result2 변수가 그리고 Result 속성의 값이 모두 동일한지 확인합니다. 기억하세요, Result 속성은 차단 속성이므로 그 작업이 완료될 때까지 접근해서는 안 됩니다.

' Display the values of the result1 variable, the result2 variable, and
' the resultTask.Result property.
textBox1.Text &= vbCrLf & $"Value of result1 variable:   {result1}" & vbCrLf
textBox1.Text &= $"Value of result2 variable:   {result2}" & vbCrLf
textBox1.Text &= $"Value of resultTask.Result:  {integerTask.Result}" & vbCrLf

작업 반환 형식

반환 문이 없거나 피연산자를 반환하지 않는 return 문이 포함된 비동기 메서드는 일반적으로 반환 형식을 Task갖습니다. 이러한 메서드는 동기적으로 실행되도록 작성된 경우 하위 프로시저가 됩니다. 비동기 메서드에 반환 형식을 사용하는 Task 경우 호출 메서드는 호출된 Await 비동기 메서드가 완료될 때까지 호출자의 완료를 일시 중단하는 연산자를 사용할 수 있습니다.

다음 예제에서 비동기 메서드 Task_MethodAsync 는 return 문을 포함하지 않습니다. 따라서 Task를 대기할 수 있도록 메서드의 반환 형식을 Task_MethodAsync로 지정합니다. Task 타입의 정의에는 반환 값을 저장할 Result 속성이 포함되어 있지 않습니다.

' TASK EXAMPLE
Async Function Task_MethodAsync() As Task

    ' The body of an async method is expected to contain an awaited
    ' asynchronous call.
    ' Task.Delay is a placeholder for actual work.
    Await Task.Delay(2000)
    textBox1.Text &= vbCrLf & "Sorry for the delay. . . ." & vbCrLf

    ' This method has no return statement, so its return type is Task.
End Function

Task_MethodAsync는 await 식 대신 await 문을 사용하여 호출되고 대기하며, 이는 동기 Sub 또는 void 반환 메서드를 호출하는 것과 유사합니다. 이 경우 연산자의 Await 애플리케이션은 값을 생성하지 않습니다.

다음 코드는 메서드 Task_MethodAsync를 호출하고 대기합니다.

' Call and await the Task-returning async method in the same statement.
Await Task_MethodAsync()

이전 Task<TResult> 예제와 마찬가지로, Task_MethodAsync 연산자의 애플리케이션과 Await 호출을 분리할 수 있음을 다음 코드에서 확인할 수 있습니다. 그러나 Task에는 Result 속성이 없고, await 연산자를 Task에 적용할 때 값이 생성되지 않습니다.

다음 코드는 호출 Task_MethodAsyncTask_MethodAsync이 반환한 작업을 기다리는 것을 구분합니다.

' Call and await in separate statements.
Dim simpleTask As Task = Task_MethodAsync()

' You can do other work that does not rely on simpleTask before awaiting.
textBox1.Text &= vbCrLf & "Application can continue working while the Task runs. . . ." & vbCrLf

Await simpleTask

Void 반환 형식

프로시저의 Sub 기본 사용은 반환 형식이 없는 이벤트 처리기에 있습니다(다른 언어에서는 void 반환 형식이라고 함). void 반환은 void 반환 메서드를 재정의하거나 "fire and forget"로 분류될 수 있는 활동을 수행하는 메서드에도 사용할 수 있습니다. 그러나 void 반환 비동기 메서드는 대기할 수 없으므로 가능한 한 반환 Task 해야 합니다. 이러한 메서드의 호출자는 호출된 비동기 메서드가 완료될 때까지 기다리지 않고 계속 완료할 수 있어야 하며 호출자는 비동기 메서드가 생성하는 값 또는 예외와 독립적이어야 합니다.

비동기 메서드(반환값 없음)의 호출자는 메서드에서 발생된 예외를 포착할 수 없으며, 이러한 처리되지 않은 예외가 애플리케이션에 오류를 일으킬 수 있습니다. 비동기 메서드가 Task 또는 Task<TResult>을 반환하는 경우 예외가 발생하면, 예외는 반환된 작업에 저장되고 작업이 대기될 때 다시 던져집니다. 따라서 예외를 생성할 수 있는 비동기 메서드의 반환 형식 Task 이 있거나 Task<TResult> 메서드에 대한 호출이 대기 중인지 확인합니다.

비동기 메서드에서 예외를 처리하는 자세한 방법에 대해서는 Try...Catch...Finally 문을 참조하세요.

다음 코드는 비동기 이벤트 처리기를 정의합니다.

' SUB EXAMPLE
Async Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click

    textBox1.Clear()

    ' Start the process and await its completion. DriverAsync is a
    ' Task-returning async method.
    Await DriverAsync()

    ' Say goodbye.
    textBox1.Text &= vbCrLf & "All done, exiting button-click event handler."
End Sub

완성된 예시

다음 WPF(Windows Presentation Foundation) 프로젝트에는 이 항목의 코드 예제가 포함되어 있습니다.

프로젝트를 실행하려면 다음 단계를 수행합니다.

  1. Visual Studio를 시작합니다.

  2. 메뉴 모음에서 파일, 새로 만들기, 프로젝트를 선택합니다.

    새 프로젝트 대화 상자가 열립니다.

  3. 설치된템플릿 범주에서 Visual Basic을 선택한 다음 Windows를 선택합니다. 프로젝트 형식 목록에서 WPF 애플리케이션 을 선택합니다.

  4. 프로젝트의 이름으로 입력 AsyncReturnTypes 한 다음 확인 단추를 선택합니다.

    새 프로젝트가 솔루션 탐색기에 나타납니다.

  5. Visual Studio Code 편집기에서 MainWindow.xaml 탭을 선택합니다.

    탭이 표시되지 않으면 솔루션 탐색기에서 MainWindow.xaml의 바로 가기 메뉴를 열고 열기를 선택합니다.

  6. MainWindow.xaml의 XAML 창에서 코드를 다음 코드로 바꿉다.

    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button x:Name="button1" Content="Start" HorizontalAlignment="Left" Margin="214,28,0,0" VerticalAlignment="Top" Width="75" HorizontalContentAlignment="Center" FontWeight="Bold" FontFamily="Aharoni" Click="button1_Click"/>
            <TextBox x:Name="textBox1" Margin="0,80,0,0" TextWrapping="Wrap" FontFamily="Lucida Console"/>
    
        </Grid>
    </Window>
    

    MainWindow.xaml의 디자인 창에 텍스트 상자와 단추가 포함된 간단한 창이 나타납니다.

  7. 솔루션 탐색기에서 MainWindow.xaml.vb 대한 바로 가기 메뉴를 연 다음 코드 보기를 선택합니다.

  8. MainWindow.xaml.vb 코드를 다음 코드로 바꿉다.

    Class MainWindow
    
        ' SUB EXAMPLE
        Async Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click
    
            textBox1.Clear()
    
            ' Start the process and await its completion. DriverAsync is a
            ' Task-returning async method.
            Await DriverAsync()
    
            ' Say goodbye.
            textBox1.Text &= vbCrLf & "All done, exiting button-click event handler."
        End Sub
    
        Async Function DriverAsync() As Task
    
            ' Task(Of T)
            ' Call and await the Task(Of T)-returning async method in the same statement.
            Dim result1 As Integer = Await TaskOfT_MethodAsync()
    
            ' Call and await in separate statements.
            Dim integerTask As Task(Of Integer) = TaskOfT_MethodAsync()
    
            ' You can do other work that does not rely on resultTask before awaiting.
            textBox1.Text &= "Application can continue working while the Task(Of T) runs. . . . " & vbCrLf
    
            Dim result2 As Integer = Await integerTask
    
            ' Display the values of the result1 variable, the result2 variable, and
            ' the resultTask.Result property.
            textBox1.Text &= vbCrLf & $"Value of result1 variable:   {result1}" & vbCrLf
            textBox1.Text &= $"Value of result2 variable:   {result2}" & vbCrLf
            textBox1.Text &= $"Value of resultTask.Result:  {integerTask.Result}" & vbCrLf
    
            ' Task
            ' Call and await the Task-returning async method in the same statement.
            Await Task_MethodAsync()
    
            ' Call and await in separate statements.
            Dim simpleTask As Task = Task_MethodAsync()
    
            ' You can do other work that does not rely on simpleTask before awaiting.
            textBox1.Text &= vbCrLf & "Application can continue working while the Task runs. . . ." & vbCrLf
    
            Await simpleTask
        End Function
    
        ' TASK(OF T) EXAMPLE
        Async Function TaskOfT_MethodAsync() As Task(Of Integer)
    
            ' The body of an async method is expected to contain an awaited
            ' asynchronous call.
            ' Task.FromResult is a placeholder for actual work that returns a string.
            Dim today As String = Await Task.FromResult(Of String)(DateTime.Now.DayOfWeek.ToString())
    
            ' The method then can process the result in some way.
            Dim leisureHours As Integer
            If today.First() = "S" Then
                leisureHours = 16
            Else
                leisureHours = 5
            End If
    
            ' Because the return statement specifies an operand of type Integer, the
            ' method must have a return type of Task(Of Integer).
            Return leisureHours
        End Function
    
        ' TASK EXAMPLE
        Async Function Task_MethodAsync() As Task
    
            ' The body of an async method is expected to contain an awaited
            ' asynchronous call.
            ' Task.Delay is a placeholder for actual work.
            Await Task.Delay(2000)
            textBox1.Text &= vbCrLf & "Sorry for the delay. . . ." & vbCrLf
    
            ' This method has no return statement, so its return type is Task.
        End Function
    
    End Class
    
  9. F5 키를 선택하여 프로그램을 실행한 다음 시작 단추를 선택합니다.

    다음 출력이 표시됩니다.

    Application can continue working while the Task<T> runs. . . .
    
    Value of result1 variable:   5
    Value of result2 variable:   5
    Value of integerTask.Result: 5
    
    Sorry for the delay. . . .
    
    Application can continue working while the Task runs. . . .
    
    Sorry for the delay. . . .
    
    All done, exiting button-click event handler.
    

참고하십시오