由于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;
}

10-05 23:46