태그: BeginInvoke

대리자는 알고리즘을 개체화하여 인자로 전달할 때 사용되는 형식입니다. 이에 대리자를 정의할 때는 알고리즘에 필요한 인자와 리턴 형식을 명시하여 정의합니다.

개발자가 대리자 형식을 정의하면 컴파일러는 MulticastDelegate를 파생한 클래스를 만들어줍니다.

[그림 45] ildasm으로 확인한 대리자
[그림 45] ildasm으로 확인한 대리자
 결국 개발자가 대리자를 정의하면 .NET 어셈블리에는 MulticastDelegate를 기반으로 파생한 클래스가 만들어지는 것입니다.

▶ delegate int DemoDele(int a, int b);를 컴파일러가 전개한 클래스

대리자 개체를 생성할 때는 시그니쳐가 같은 메서드를 입력 인자로 생성합니다. 그리고 대리자 선언문에서 시그니쳐가 같은 메서드로 초기화를 해도 대리자 개체가 생성됩니다.

▶ 대리자 개체 생성

대리자 개체는 이름이 없는 메서드를 이용하여 생성할 수도 있습니다.

▶ 무명 대리자 개체 생성

대리자 개체는 메서드처럼 사용할 수 있으며 생성할 때 입력 인자로 전달한 메서드가 수행됩니다. 대리자 개체를 메서드처럼 사용하면 내부적으로는 Invoke 메서드가 호출됩니다. 실제로 Invoke 메서드를 호출해도 되며 이 둘의 차이는 없습니다.

▶ 메서드처럼 호출과 Invoke 메서드 호출

▶ 실행 결과

 

그리고 대리자는 서로 더하거나 빼기를 통해 수행할 메서드를 추가하거나 뺄 수 있습니다. 이는 기반 형식인 MulticastDelegate에서 제공하는 기능을 상속받기 때문이며 여러 메서드를 수행하는 대리자의 결과는 맨 마지막에 수행한 메서드의 결과입니다.

▶ 대리자의 더하기와 빼기

▶ 실행 결과

 

대리자 개체의 BeginInvoke 메서드를 이용하면 수행할 메서드를 비동기적으로 호출할 수 있습니다. 하지만 BeginInvoke 메서드로 비동기로 대리자를 호출하려면 대상 메서드가 하나여야 합니다.

BeginInvoke 메서드를 호출할 때는 대리자 선언에 명시한 입력 인자와 비동기 작업이 완료 시에 수행할 종료 콜백 메서드와 종료 콜백 메서드에 전달할 인자를 전달할 수 있습니다. 종료 콜백 메서드의 시그니쳐는 리턴 형식이 void이며 입력 인자로 IAsyncResult입니다.

▶ 종료 콜백 메서드의 예

그리고 종료 콜백 메서드에서는 EndInvoke 메서드를 호출하여 비동기로 대리자를 호출한 작업을 정상적으로 종료하세요. 종료 콜백 메서드의 입력 인자로 전달된 IAsyncResult 개체를 참조 연산으로 AsyncResult 개체를 참조하여 AsyncDelegate 속성으로 대리자 개체를 가져올 수 있습니다. 그리고 대리자 개체의 EndInvoke 메서드를 호출하면 작업 결과를 반환받아 사용할 수 있습니다.

▶ 종료 콜백 메서드의 예

종료 콜백 메서드에 null을 인자로 전달할 때는 BeginInvoke에서 전달받은 IAsyncResult 개체의 IsCompleted 속성을 확인하여 요청한 비동기 작업이 완료되었는지를 확인할 수 있습니다. 그리고 EndInvoke 메서드를 호출하여 비동기 작업을 종료할 수 있으며 작업 결과를 반환받아 사용할 수 있습니다.

▶ 비동기로 대리자 호출

▶ 실행 결과

예제 코드는 비동기 작업이 있어서 실제 수행 결과는 다양하게 나옵니다.