2017-02-03 83 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