如何转换 Task<TDerived>到任务<TBase>? [英] How to convert a Task&lt;TDerived&gt; to a Task&lt;TBase&gt;?

查看:15
本文介绍了如何转换 Task<TDerived>到任务<TBase>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 C# 的 Task 是一个类,因此您显然不能将 Task 转换为 Task.

Since C#'s Task is a class, you obviously can't cast a Task<TDerived> to a Task<TBase>.

但是,您可以:

public async Task<TBase> Run() {
    return await MethodThatReturnsDerivedTask();
}

是否有我可以调用的静态任务方法来获取 Task 实例,该实例基本上只是指向底层任务并转换结果?我想要类似的东西:

Is there a static task method I can call to get a Task<TDerived> instance which essentially just points to the underlying task and casts the result? I'd like something like:

public Task<TBase> Run() {
    return Task.FromDerived(MethodThatReturnsDerivedTask());
}

有这样的方法吗?仅为此目的使用异步方法是否有任何开销?

Does such a method exist? Is there any overhead to using an async method solely for this purpose?

推荐答案

有这种方法吗?

没有

仅为此目的使用异步方法是否有任何开销?

Is there any overhead to using an async method solely for this purpose?

是的.但这是最简单的解决方案.

Yes. But it's the easiest solution.

请注意,更通用的方法是Task 的扩展方法,例如Then.Stephen Toub 在一篇博文中探讨了这个我最近将它合并到AsyncEx.

Note that a more generic approach is an extension method for Task such as Then. Stephen Toub explored this in a blog post and I've recently incorporated it into AsyncEx.

使用 Then,您的代码将如下所示:

Using Then, your code would look like:

public Task<TBase> Run()
{
  return MethodThatReturnsDerivedTask().Then(x => (TBase)x);
}

另一种开销稍少的方法是创建您自己的 TaskCompletionSource 并使用派生结果完成它(使用我的 AsyncEx 库中的 TryCompleteFromCompletedTask):

Another approach with slightly less overhead would be to create your own TaskCompletionSource<TBase> and have it completed with the derived result (using TryCompleteFromCompletedTask in my AsyncEx library):

public Task<TBase> Run()
{
  var tcs = new TaskCompletionSource<TBase>();
  MethodThatReturnsDerivedTask().ContinueWith(
      t => tcs.TryCompleteFromCompletedTask(t),
      TaskContinuationOptions.ExecuteSynchronously);
  return tcs.Task;
}

或(如果您不想依赖 AsyncEx):

or (if you don't want to take a dependency on 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;
}

这篇关于如何转换 Task<TDerived>到任务<TBase>?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆