2017-02-03 86 views
2

我必須使用一個API來強制實現其回調接口的類作爲身份驗證方法的參數。如何強制任務等待子任務?

public class CallBack : ICallBack 
{ 
    public object Response; 
    public void OnSuccess(object response) 
    { 
     Response = response; 
    } 
    public void OnException(Exception ex) { } 
} 

驗證呼叫

public async Task<bool> LoginAsync(string username, string password) 
{ 
    CallBack callback = new CallBack(); 
    await Task.Factory.StartNew(
     () => userService.Authenticate(username, password, callback), 
      TaskCreationOptions.AttachedToParent); 
    return callback.Response is User ? true : false; 
} 

的問題是,在回調之前LoginAsync完成被調用。我希望通過使用TaskCreationOptions.AttachedToParent啓動Authenticate呼叫,它會傳播到在Authenticate開始的任何子任務,但它不會。

+1

請參閱[將基於回調的異步方法轉換爲等待任務的最佳方式](http://stackoverflow.com/questions/11879967/best-way-to-convert-callback-based-async-method-to-awaitable-任務) – Kalten

+0

什麼是'callback.ReturnValue'?我沒有在你的課堂上看到這樣的屬性 – CodingYoshi

+0

修正了這個問題。應該是callback.Response – user3578834

回答

4

您應該使用TaskCompletionSource對象將基於回調的異步方法包裝爲等待任務。

我假設你ICallBack是這樣的:

public interface ICallBack 
{ 
    void OnSuccess(object response); 
    void OnException(Exception ex); 
} 

所以,你可以這樣實現LoginAsync:

public async Task<bool> LoginAsync(string username, string password) 
{ 
    var tcs = new TaskCompletionSource<object>(); 
    ICallBack callback = new CallBackAsync(tcs); 
    userService.Authenticate(username, password, callback); 
    var result = await tcs.Task; 
    return result is User ? true : false; 
} 

public class CallBackAsync : ICallBack 
{ 
    private TaskCompletionSource<object> _tcs; 
    public CallBackAsync(TaskCompletionSource<object> tcs) 
    { 
     _tcs = tcs; 
    } 

    public void OnSuccess(object response) 
    { 
     _tcs.TrySetResult(response); 
    } 
    public void OnException(Exception ex) { 
     _tcs.TrySetException(ex); 
    } 
} 

對於簡單解釋,當您使用Task.Factory.StartNew()在lambda表達式的末尾提出完成任務。但在你的情況下,這發生在CallBack.OnSuccess調用之前。所以結果沒有設置。

TaskCompletionSource類允許您完全控制何時必須完成任務完成。

+0

你爲什麼不解釋爲什麼OP的代碼不起作用? (大概OP是能夠適應代碼自己從鏈接http://stackoverflow.com/questions/11879967/best-way-to-convert-callback-based-async-method-to-awaitable-task你已經給) –

+0

我認爲代碼示例是比長文本更好的解釋。而且我不太習慣用英文書寫長文本。 – Kalten

+0

這工作完美!現在找出爲什麼 – user3578834