我必须使用一个API,该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在调用回调之前就完成了。我希望通过使用Authenticate启动TaskCreationOptions.AttachedToParent调用,它将向下传播到在Authenticate中启动的任何子任务,但它没有。
发布于 2017-02-03 23:54:26
您应该使用一个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类允许您完全控制必须完成任务的时间。
https://stackoverflow.com/questions/42034621
复制相似问题