현재 실행중인 메인스레드가 아닌 다른 스레드의 메소드를 호출하고 그 메소드가 완료되었을 때 비동기적으로 완료 보고를 받을 수 없을까?

델리게이트는 이런 기능을 이미 갖고있다.
델리게이트는 함수를 포인팅을 할수 있는 클래스로 델리게이트를 정의 하면 하나의 감춰진 객체가 하나 동적으로  생성된다.
이 객체는 System.MulticastDelegate 를 상속하는 것으로, 내부적으로 이런 비동기 동작을 지원할 수 있도록
BeginInvoke() 와 EndInvoke() 메소드를 내장하고 있다.
하지만 이 메소드는 컴파일전에 인텔리센스에 나오지않는다. 동적으로 생성하기 때문이다.
비동기 호출을 하게 되면 새로운 스레드가 생성되고 새로운 스레드에서 메소드가 실행된후 메인스레드로 리턴한다.

Console.WriteLine("Main Thread {0}", Thread.CurrentThread.GetHashCode());
NewDelegate d = new NewSomeDelegate(SomeFunc);

IAsyncResult result = d.BeginInvoke(); //result 는 비동기 스레드 상태정보, EndInvoke  때 넘겨주자
//.... 다른 작업

//비동기 호출 결가를 받고자 할때 (SomeFunc 가 string 을 리턴한다면..)
string ret = d.EndInvoke(result);

여기서 SomeFunc 에서 Thread.CurrentThread.GetHashCode() 를 찍어보면 호출한 메인 스레드와 SomeFunc 가 실행된 스레드의 해시값이 다름을 알수있다.


EndInvoke 호출 없이 바로 결과를 알고 싶은 경우 콜백 함수를 지정해서 BeginInvoke 할 수도 있다.
이 콜백 형식은 AsysncCallback 형 델리게이트다.
즉, AsysncCallback 형 함수를 하나 만들고 BeginInvoke 시 델리게이트로 포장해 넘기면 비동기 호출의 콜백으로 호출된다는 것이다.(AsysncCallback 형 함수는 static 이거나 같은 인스턴스 레벨에 있어야 한다.)

* AsyncResult 클래스는 System.RunTime.Remoting.Messaging 네임스페이스에 있다.

public static CallbackFunc(IAsyncResult result)
{
...
//AsyncResult  res= (AsyncResult)result ; 이렇게 사용할 수 있다.
// res.AsyncDelegate 를 원해 호출한 델리게이트 형으로 캐스팅하여 얻어 올수있다.
// 여기서는 NewSomeDelegate d = (NewSomeDelegate)res.AsyncDelegate ; 이렇게 할 수 있다.
// EndInvoke 를 호출해 반환 값을 얻는다.

//델리게이트가 스트링을 리턴하는 형태이므로
string result = ((NewSomeDelegate)((AsyncResult)result).AsyncDelegate).EndInvoke(result);

}

이렇게 콜백 AsysncCallback 형 함수를 하나 만들고

NewDelegate d = new NewSomeDelegate(SomeFunc);
d.BeginInvoke(new AsyncCallback(CallbackFunc),null);

하면...다른 스레드에서 함수가 실행되고 콜백이 호출된 후 콜백에서 EndInvoke 로 리턴 값을 받을 수 있다.









댓글을 달아 주세요