[英]How to Force Task To Wait for Child Tasks?
我必須使用一個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
在調用回調之前完成。 我希望通過使用TaskCreationOptions.AttachedToParent
啟動Authenticate
調用,它可以傳播到在Authenticate
啟動的所有子任務,但不會。
您應該使用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類使您可以完全控制何時必須完成任務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.