2013-10-09 2 views
0

async을 사용하지 않고 기존 스레드와 콜백을 사용하는 멀티 스레드 라이브러리를 사용하고 있습니다.스레드 콜백을 대기하는 방법은 무엇입니까?

그래서 같이 async 함수에서이 코드를 호출 오전 을

var connection = new SomeLib(); 
connection.OnConnected += (x) => { /* This is called from separate thread */ } 
connection.Connect(); 
을 을 :

public async Task<Boolean> MyFunc() 
{ 
    var connection = new SomeLib(); 
    connection.OnConnected += (x) => { /* This is called from separate thread */ } 
    connection.Connect(); 

    // ... 

    // Need to return after OnConnected has been fired. 
    return true; 
} 

가 어떻게이 OnConnected 콜백은 "대기"내 기능을 가지고 await를 사용하여 호출 될?

+2

반환 할 문자열은 무엇입니까? 제일 먼저 할 일은'TaskCompletionSource'를 추적하는 합리적으로 간단한 방법으로 사용할 수있는'ConnectAsync' 메소드 (또는 확장 메소드)를 작성하는 것입니다. –

+0

문자열은 중요하지 않습니다. 이것은 단지 장난감의 예일뿐입니다. ConnectAsync 메서드를 작성하면 무슨 뜻입니까? 나는 내가 사용하고있는 도서관의 출처를 바꿀 수 없다는 것을 언급해야한다. –

+0

@JonSkeet 죄송합니다. 내 의견을 제거하겠습니다. –

답변

3

다음은 EventHandler <> 유형 이벤트에서 작동하지만 다른 서명 위임자에서 작동하도록 쉽게 조정할 수 있습니다. 먼저 도우미 함수 (EventToATaskAsync)가 ch는 덧셈기를 제거하고 이벤트를 설정/해제하는 대리인을 제거합니다.

이 메커니즘을 사용하는 단점은 래핑 된 비동기 작업마다 확장 메서드를 작성해야한다는 것입니다.

public static Task<A> EventToTaskAsync<A>(Action<EventHandler<A>> adder, Action<EventHandler<A>> remover) 
{ 
    System.Threading.Tasks.TaskCompletionSource<A> tcs = new TaskCompletionSource<A>(); 
    EventHandler<A> onComplete = null; 
    onComplete = (s, e) => 
    { 
     remover(onComplete); 
     tcs.SetResult(e); 
    }; 
    adder(onComplete); 
    return tcs.Task; 
} 

그런 다음 일반적으로 기존 클래스에 작업 기능을 추가하기 위해 확장 호출을 사용하여 포장합니다. 다음 예제에서, 나는 (하지만 이벤트 메커니즘을 사용하여 거의 아무것도 그렇게 할 수) 스토리 보드에 BeginAsync를 추가하고 : 도움이

public static Task BeginAsync(this Storyboard storyboard) 
    { 
     return EventToTaskAsync<object>(
       e => { storyboard.Completed += e; storyboard.Begin(); }, 
       e => storyboard.Completed -= e); 
    } 

희망을.

-1

대기 핸들을 사용하여이 작업을 수행 할 수 있습니다. 트리거 핸들 대기, 연결 호출하는 기능에

waitForConnect.Set(); 

: 트리거, 핸들을 OnConnected 핸들러에서

private waitForConnect = new AutoResetEvent(false); 

: 먼저 AutoResetEvent를 정의

connection.Connect(); 
waitForConnect.WaitOne(); // This will sleep the thread until connected 
+1

비동기 메서드 (콜백 스타일이든 또는 async'-'와 같은 것이 든)의 요점은 그들이 * 블록하지 않는다는 것입니다 *. 그래서 나는이 일을하는 것이 의미가 없다고 생각합니다. – svick

+0

@svick : 참으로, 내 실수 ... – Bigjim

관련 문제