由于C#的Task是一个类,因此您显然无法将Task<TDerived>
转换为Task<TBase>
。
但是,您可以执行以下操作:
public async Task<TBase> Run() {
return await MethodThatReturnsDerivedTask();
}
我是否可以调用静态任务方法来获取
Task<TDerived>
实例,该实例实际上仅指向基础任务并强制转换结果?我想要类似的东西:public Task<TBase> Run() {
return Task.FromDerived(MethodThatReturnsDerivedTask());
}
是否存在这种方法?仅为此目的使用异步方法会产生任何开销吗?
最佳答案
不。
是的。但这是最简单的解决方案。
注意,更通用的方法是Task
的扩展方法,例如Then
。 Stephen Toub探索了这个in a blog post,我最近浏览了incorporated it into AsyncEx。
使用Then
,您的代码如下所示:
public Task<TBase> Run()
{
return MethodThatReturnsDerivedTask().Then(x => (TBase)x);
}
开销稍少的另一种方法是创建自己的
TaskCompletionSource<TBase>
并用派生结果完成(使用我的AsyncEx库中的TryCompleteFromCompletedTask
):public Task<TBase> Run()
{
var tcs = new TaskCompletionSource<TBase>();
MethodThatReturnsDerivedTask().ContinueWith(
t => tcs.TryCompleteFromCompletedTask(t),
TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
或(如果您不想依赖AsyncEx):
public Task<TBase> Run()
{
var tcs = new TaskCompletionSource<TBase>();
MethodThatReturnsDerivedTask().ContinueWith(t =>
{
if (t.IsFaulted)
tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled)
tcs.TrySetCanceled();
else
tcs.TrySetResult(t.Result);
}, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}