我想使用TaskCompletionSource
来包装一个简单服务MyService
:
public static Task<string> ProcessAsync(MyService service, int parameter)
{
var tcs = new TaskCompletionSource<string>();
//Every time ProccessAsync is called this assigns to Completed!
service.Completed += (sender, e)=>{ tcs.SetResult(e.Result); };
service.RunAsync(parameter);
return tcs.Task;
}
这段代码第一次运行得很好。但是第二次调用ProcessAsync
时,只是简单地重新分配Completed
事件处理程序(每次都使用相同的service
变量),因此它会执行两次!第二次会抛出以下异常:
尝试在已完成的任务终态下转换任务状态
我不确定,是否应该像这样将tcs
声明为类级别变量:
TaskCompletionSource<string> tcs;
public static Task<string> ProccessAsync(MyService service, int parameter)
{
tcs = new TaskCompletionSource<string>();
service.Completed -= completedHandler;
service.Completed += completedHandler;
return tcs.Task;
}
private void completedHandler(object sender, CustomEventArg e)
{
tcs.SetResult(e.Result);
}
我必须包装许多返回类型不同的方法,这样我就必须编写大量的代码、变量和事件处理程序,因此我不确定这是否是在这种情况下最佳实践。那么有没有更好的方法来完成这项工作呢?
service.Completed-=callback;
处无法隐式地将Action<...,...>转换为EventHandler<...>,所以我通过更改类型来修复它。 - Hossein Narimani Radservice.Completed -= callback
看起来像是魔法。它是如何将这个新创建的变量与之前分配的变量进行比较并匹配它们的? - Hossein Narimani Rad