2013-04-25 12 views
3

我使用一個名爲DoWork(...)的異步方法的庫,當操作完成時將引發一個WorkDone事件。如何使用異步/等待與使用基於事件的異步模式的庫?

我想寫一個方法來調用這個庫,但不是保持相同的模式,我想我的方法是async,所以它可以調用await

從本質上說,我所要做的是:

public async Task<Result> SomeMethod() 
{ 
    var result = new Task<Result>(); 

    library.WorkDone += (data) => 
    { 
     result.Result = data; 
    } 
    library.DoWork(); 

    return await result; 
} 

(不工作,因爲結果是隻讀)

可以這樣做?

回答

5

我將建立在ws0205的回答是:

首先,表明你希望你的方法 「與await被稱爲」。您通過返回Task來實現此目的。

我也認爲這是更好地進行以下調整ws0205的回答是:

public Task<Result> SomeMethod() //no async, since we're not awaiting anything 
{ 
    var result = new TaskCompletionSource<Result>(); 

    library.WorkDone += (data) => 
           { 
            result.TrySetResult(data); //just in case 
           }; 
    library.DoWork(); 

    return result.Task; //no need to await - we're returning a Task - let the caller await (or not) 
} 
+0

好吧,這工作也是如此。我在Web服務器中使用這個,你能否確認這不會阻塞線程,即使沒有async關鍵字? – 2013-04-25 07:17:25

+0

@ G.Stoynev的右邊,線程不會被阻塞,因爲你返回Task,那些使用它的人需要使用'await'關鍵字。 – 2013-04-25 07:20:23

+1

有關更多信息,請參見MSDN文檔(http://msdn.microsoft.com/zh-cn/library/hh873178.aspx#EAP)。 – 2013-04-25 12:20:04

2

您可以使用TaskCompletionSource

public async Task<Result> SomeMethod() 
{ 
    var result = new TaskCompletionSource<Result>(); 

    library.WorkDone += (data) => 
           { 
            result.SetResult(data); 
           }; 
    library.DoWork(); 

    return await result.Task; 
}