다음을 통해 공유


이벤트 기반 비동기 패턴 구현

업데이트: 2007년 11월

인식 가능한 지연을 유발할 수 있는 작업을 사용하여 클래스를 작성할 경우 이벤트 기반 비동기 패턴 개요를 구현하여 비동기 기능을 제공할 수 있습니다.

이벤트 기반 비동기 패턴은 비동기 기능을 포함하는 클래스를 패키지화하는 표준화된 방법을 제공합니다. AsyncOperationManager와 같은 도우미 클래스로 구현한 클래스는 ASP.NET, 콘솔 응용 프로그램 및 Windows Forms 응용 프로그램을 비롯한 모든 응용 프로그램 모델에서 제대로 작동됩니다.

이벤트 기반 비동기 패턴을 구현하는 예제를 보려면 방법: 이벤트 기반 비동기 패턴을 지원하는 구성 요소 구현을 참조하십시오.

간단한 비동기 작업의 경우 BackgroundWorker 구성 요소가 적합합니다. BackgroundWorker에 대한 자세한 내용은 방법: 백그라운드에서 작업 실행을 참조하십시오.

다음 목록에서는 이 항목에 소개된 이벤트 기반 비동기 패턴의 기능을 설명합니다.

  • 이벤트 기반 비동기 패턴을 구현할 수 있는 경우

  • 비동기 메서드 명명

  • 선택적인 취소 지원

  • 선택적인 IsBusy 속성 지원

  • 선택적인 진행률 보고 지원

  • 선택적인 증분 결과 반환 지원

  • 메서드의 Out 및 Ref 매개 변수 처리

이벤트 기반 비동기 패턴을 구현할 수 있는 경우

다음과 같은 경우에 이벤트 기반 비동기 패턴을 구현할 수 있습니다.

  • 클래스 클라이언트에 비동기 작업에 사용할 수 있는 WaitHandleIAsyncResult 개체가 필요하지 않은 경우. 즉 클라이언트에서 폴링과 WaitAll 또는 WaitAny를 작성해야 합니다.

  • 클라이언트에서 친숙한 이벤트/대리자 모델을 사용하여 비동기 작업을 관리하도록 하려는 경우

어떠한 작업이든지 비동기식으로 구현할 수 있지만 대기 시간이 길 것으로 예상되는 작업을 우선적으로 고려해야 합니다. 특히 클라이언트에서 메서드를 호출하고 완료 시 알림을 받되 추가 조치가 필요하지 않은 작업이 비동기식 구현에 적합합니다. 또한 지속적으로 실행되면서 클라이언트에 진행률, 증분 결과 또는 상태 변화를 주기적으로 알려주는 작업도 비동기식 구현에 적합합니다.

이벤트 기반 비동기 패턴을 지원해야 할 경우를 결정하는 방법에 대한 자세한 내용은 이벤트 기반 비동기 패턴 구현 시기 결정을 참조하십시오.

비동기 메서드 명명

비동기 메서드를 제공하려는 각 동기 메서드 MethodName에 대해 다음을 수행합니다.

다음 작업을 수행하는 MethodNameAsync 메서드를 정의합니다.

  • void를 반환합니다.

  • MethodName 메서드와 동일한 매개 변수를 사용합니다.

  • 다중 호출을 허용합니다.

필요에 따라 MethodNameAsync와 동일하지만 userState라는 추가 개체 값 매개 변수가 있는 MethodNameAsync 오버로드를 정의합니다. 이 작업은 메서드의 여러 동시 호출을 관리할 준비가 된 경우에 수행합니다. 이 경우 메서드 호출을 구분하기 위해 userState 값이 모든 이벤트 처리기로 다시 전달됩니다. 또한 나중에 검색하기 위해 사용자 상태를 저장하는 수단으로도 이 방식을 선택할 수 있습니다.

별도의 MethodNameAsync 메서드 시그니처 각각에 대해 다음을 수행합니다.

  1. 메서드와 동일한 클래스에 다음 이벤트를 정의합니다.

    Public Event MethodNameCompleted As MethodNameCompletedEventHandler
    
    public event MethodNameCompletedEventHandler MethodNameCompleted;
    
  2. 다음 대리자 및 AsyncCompletedEventArgs를 정의합니다. 이러한 항목은 클래스 자체의 외부이면서 동일한 네임스페이스에 정의될 수 있습니다.

    Public Delegate Sub MethodNameCompletedEventHandler( _
        ByVal sender As Object, _
        ByVal e As MethodNameCompletedEventArgs)
    
    Public Class MethodNameCompletedEventArgs
        Inherits System.ComponentModel.AsyncCompletedEventArgs
    Public ReadOnly Property Result() As MyReturnType
    End Property
    
    public delegate void MethodNameCompletedEventHandler(object sender, 
        MethodNameCompletedEventArgs e);
    
    public class MethodNameCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
    {
        public MyReturnType Result { get; }
    }
    
    • 필드에서는 데이터 바인딩이 불가능하므로 MethodNameCompletedEventArgs 클래스가 해당 멤버를 필드가 아닌 읽기 전용 속성으로 노출하도록 합니다.

    • 결과를 생성하지 않는 메서드에 대해서는 AsyncCompletedEventArgs 파생 클래스를 정의하지 않고 AsyncCompletedEventArgs 인스턴스 자체를 사용합니다.

      참고:

      적절하고 편리한 상황이라면 대리자 및 AsyncCompletedEventArgs 형식을 얼마든지 다시 사용할 수 있습니다. 이 경우 지정된 대리자 및 AsyncCompletedEventArgs가 단일 메서드에 연결되지 않으므로 메서드 이름과 동일한 방식으로 이름이 지정되지 않습니다.

선택적인 취소 지원

클래스가 비동기 작업의 취소를 지원할 경우 아래에 설명된 것처럼 클라이언트에 취소가 노출되어야 합니다. 취소 지원을 정의하기 전에 다음의 두 가지 사항을 결정해야 합니다.

  • 현재 및 앞으로 추가될 클래스에 취소를 지원하는 비동기 작업이 하나만 있습니까?

  • 취소를 지원하는 비동기 작업이 보류 중인 다중 작업을 지원할 수 있습니까? 즉, MethodNameAsync 메서드가 userState 매개 변수를 사용하며 하나의 호출이 끝나기를 기다리지 않고 여러 번 호출할 수 있도록 허용합니까?

아래 표에 제공된 이러한 두 질문에 대한 대답을 참조하여 취소 메서드에 대한 시그니처를 결정하십시오.

Visual Basic

 

다중 동시 작업 지원

한 번에 한 작업만 지원

전체 클래스에서 단일 비동기 작업

Sub MethodNameAsyncCancel(ByVal userState As Object)
Sub MethodNameAsyncCancel()

클래스에서 다중 비동기 작업

Sub CancelAsync(ByVal userState As Object)
Sub CancelAsync()

C#

 

다중 동시 작업 지원

한 번에 한 작업만 지원

전체 클래스에서 단일 비동기 작업

void MethodNameAsyncCancel(object userState);
void MethodNameAsyncCancel();

클래스에서 다중 비동기 작업

void CancelAsync(object userState);
void CancelAsync();

CancelAsync(object userState) 메서드를 정의하는 경우 클라이언트는 단일 비동기 메서드의 모든 호출 간을 구분하는 것뿐만 아니라 개체에 대해 호출된 여러 비동기 메서드 간을 구분할 수 있도록 주의해서 상태 값을 선택해야 합니다.

Visual Studio의 IntelliSense와 같은 디자인 환경에서 메서드를 보다 쉽게 검색할 수 있도록 하기 위해 단일 비동기 작업 버전을 MethodNameAsyncCancel로 명명하고 있습니다. 이를 통해 관련 멤버가 그룹화되고 비동기 기능과 관련이 없는 다른 멤버와 구분됩니다. 이후 버전에 다른 비동기 작업이 추가될 예정이면 CancelAsync를 정의하는 것이 좋습니다.

위의 표에 나오는 여러 메서드를 동일한 클래스에 정의하지 마십시오. 상황에 맞지 않거나 메서드가 늘어나서 클래스 인터페이스가 복잡해질 수 있습니다.

이러한 메서드는 일반적으로 즉시 반환되며 해당 작업은 실제로 취소되거나 취소되지 않을 수 있습니다. MethodNameCompleted 이벤트에 대한 이벤트 처리기에서 MethodNameCompletedEventArgs 개체는 클라이언트가 취소 발생 여부를 확인하는 데 사용할 수 있는 Cancelled 필드를 포함합니다.

최선의 이벤트 기반 비동기 패턴 구현 방법에 설명된 취소 의미 체계를 따르십시오.

선택적인 IsBusy 속성 지원

클래스가 여러 동시 호출을 지원하지 않으면 IsBusy 속성을 노출할 수 있습니다. 이 방법을 사용하면 개발자들은 MethodNameAsync 메서드에서 예외를 catch하지 않고도 MethodNameAsync 메서드가 실행 중인지 여부를 확인할 수 있습니다.

최선의 이벤트 기반 비동기 패턴 구현 방법에 설명된 IsBusy 의미 체계를 따르십시오.

선택적인 진행률 보고 지원

일반적으로 비동기 작업은 진행 중에 진행률을 보고하도록 하는 것이 좋습니다. 이벤트 기반 비동기 패턴은 이렇게 하기 위한 지침을 제공합니다.

  • 필요에 따라 비동기 작업에 의해 발생되고 적절한 스레드에서 호출될 이벤트를 정의합니다. ProgressChangedEventArgs 개체는 0에서 100 사이의 정수 값 진행률 표시기를 제공합니다.

  • 다음에 따라 이 이벤트의 이름을 지정하십시오.

    • 클래스에 다중 비동기 작업이 있거나 이후 버전에서 여러 비동기 작업을 포함하도록 확장될 예정인 경우 ProgressChanged

    • MethodName 클래스에 단일 비동기 작업이 있는 경우 ProgressChanged

    이 이름 지정 방법은 선택적인 취소 지원 단원에 설명된 취소 메서드의 이름 지정 방법과 비슷합니다.

이 이벤트는 ProgressChangedEventHandler 대리자 시그니처 및 ProgressChangedEventArgs 클래스를 사용해야 합니다. 또는 도메인과 보다 밀접하게 관련된 진행률 표시기를 제공할 수 있는 경우(예: 다운로드 작업에 대한 읽은 바이트 수 및 총 바이트 수) ProgressChangedEventArgs의 파생 클래스를 정의해야 합니다.

클래스가 지원하는 비동기 메서드의 수에 관계없이 해당 클래스에 대한 ProgressChanged 또는 MethodNameProgressChanged 이벤트는 하나만 있습니다. 클라이언트는 여러 동시 작업에 대한 진행률 업데이트 내용을 구분하기 위해 MethodNameAsync 메서드에 전달되는 userState 개체를 사용하게 됩니다.

여러 작업이 진행률을 지원하고 작업마다 각기 다른 진행률 표시기를 반환할 수 있습니다. 이 경우 단일 ProgressChanged 이벤트로는 적합하지 않으며 여러 ProgressChanged 이벤트를 지원할 수 있습니다. 이 경우 각 MethodNameAsync 메서드에 대해 MethodNameProgressChanged 명명 패턴을 사용하십시오.

최선의 이벤트 기반 비동기 패턴 구현 방법에 설명된 진행률 보고 의미 체계를 따르십시오.

선택적인 증분 결과 반환 지원

경우에 따라 비동기 작업은 완료되기 전에 증분 결과를 반환할 수 있습니다. 이 시나리오를 지원하기 위해 다양한 옵션을 사용할 수 있습니다. 다음에 제공되는 몇 가지 예제를 참조하십시오.

단일 작업 클래스

클래스가 단일 비동기 작업만 지원하며 해당 작업이 증분 결과를 반환할 수 있는 경우 다음을 수행합니다.

  • 증분 결과 데이터를 전달하도록 ProgressChangedEventArgs 형식을 확장하고 확장된 데이터로 MethodNameProgressChanged 이벤트를 정의합니다.

  • 보고할 증분 결과가 있을 때 MethodNameProgressChanged 이벤트를 발생시킵니다.

이 솔루션은 MethodNameProgressChanged 이벤트처럼 "모든 작업"에 대한 증분 결과를 반환하기 위해 동일한 이벤트가 발생되는 문제가 없으므로 단일 비동기 작업 클래스에 특수하게 적용됩니다.

유형이 같은 증분 결과를 갖는 다중 작업 클래스

이 경우 클래스는 각각 증분 결과를 반환할 수 있는 여러 비동기 메서드를 지원하며 이러한 증분 결과의 데이터 형식은 모두 동일합니다.

모든 증분 결과에 동일한 EventArgs 구조체가 작동하므로 위에 설명된 단일 작업 클래스 관련 모델을 따릅니다. MethodNameProgressChanged 이벤트 대신 다중 비동기 메서드에 적용되는 ProgressChanged 이벤트를 정의합니다.

유형이 다른 증분 결과를 갖는 다중 작업 클래스

클래스가 각각 다른 데이터 형식을 반환하는 여러 비동기 메서드를 지원할 경우 다음을 수행합니다.

  • 진행률 보고 내용과 증분 결과 보고 내용을 분리합니다.

  • 각 비동기 메서드가 해당 메서드의 증분 결과 데이터를 처리할 수 있도록 적절한 EventArgs를 사용하여 별도의 MethodNameProgressChanged 이벤트를 정의합니다.

최선의 이벤트 기반 비동기 패턴 구현 방법에 설명된 대로 적절한 스레드에서 해당 이벤트 처리기를 호출합니다 .

메서드의 Out 및 Ref 매개 변수 처리

일반적으로 .NET Framework에서는 out 및 ref를 사용하는 것이 권장되지 않지만 이러한 매개 변수를 사용할 때는 다음과 같은 규칙을 따라야 합니다.

동기 메서드를 MethodName으로 명명한 경우

  • MethodName에 대한 out 매개 변수는 MethodNameAsync에 속하면 안 되며 좀 더 적절한 이름이 없는 경우 MethodName의 동일한 매개 변수와 이름이 같은 MethodNameCompletedEventArgs에 속해야 합니다.

  • MethodName에 대한 ref 매개 변수는 좀 더 적절한 이름이 없는 경우 MethodName의 동일한 매개 변수와 이름이 같은 MethodNameAsync 및 MethodNameCompletedEventArgs에 속해야 합니다.

예를 들면, 다음과 같습니다.

Public Function MethodName(ByVal arg1 As String, ByRef arg2 As String, ByRef arg3 As String) As Integer
public int MethodName(string arg1, ref string arg2, out string arg3);

비동기 메서드 및 해당 AsyncCompletedEventArgs 클래스는 다음과 같습니다.

Public Sub MethodNameAsync(ByVal arg1 As String, ByVal arg2 As String)

Public Class MethodNameCompletedEventArgs
    Inherits System.ComponentModel.AsyncCompletedEventArgs
    Public ReadOnly Property Result() As Integer 
    End Property
    Public ReadOnly Property Arg2() As String 
    End Property
    Public ReadOnly Property Arg3() As String 
    End Property
End Class
public void MethodNameAsync(string arg1, string arg2);

public class MethodNameCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
    public int Result { get; };
    public string Arg2 { get; };
    public string Arg3 { get; };
}

참고 항목

작업

방법: 이벤트 기반 비동기 패턴을 지원하는 구성 요소 구현

방법: 백그라운드에서 작업 실행

방법: 백그라운드 작업을 사용하는 폼 구현

개념

이벤트 기반 비동기 패턴 구현 시기 결정

최선의 이벤트 기반 비동기 패턴 구현 방법

참조

ProgressChangedEventArgs

AsyncCompletedEventArgs

기타 리소스

이벤트 기반 비동기 패턴을 사용한 다중 스레드 프로그래밍