如何将任务&LT转换; TDerived>给任务< TBASE&GT ;? [英] How to convert a Task<TDerived> to a Task<TBase>?

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

问题描述

由于C#的任务是一个类,你显然不能投了任务< TDerived> 任务< TBASE>

不过,你可以这样做:

 公共异步任务< TBASE>跑() {
    返回等待MethodThatReturnsDerivedTask();
}

有没有一种静态任务的方法我可以打电话获得任务< TDerived> 实例,它本质上只是指向底层的任务,并投下的结果呢?我想是这样的:

 公共任务< TBASE>跑() {
    返回Task.FromDerived(MethodThatReturnsDerivedTask());
}

请问这样的方法存在吗?是否有任何开销使用异步方法只用于此目的?


解决方案

  

请问这样的方法存在吗?


没有。


  

有任何开销使用异步方法只用于此目的?


是的。但是,这是最简单的解决方案。

请注意,一个更通用的方法是工作扩展方法,如然后。斯蒂芬Toub在一篇博客文章探讨过这个而我最近<一个href=\"http://nitoasyncex.$c$cplex.com/wikipage?title=TaskExtensions&referringTitle=Documentation\">incorporated它变成AsyncEx

使用然后,您的code看起来像:

 公共任务&LT; TBASE&GT;跑()
{
  返回MethodThatReturnsDerivedTask()然后(X =&GT;(TBASE)X)。
}

略少开销另一种方法是创建自己的 TaskCompletionSource&LT; TBASE&GT; ,并将它与派生结果完成(使用 TryCompleteFromCompletedTask 在我AsyncEx库):

 公共任务&LT; TBASE&GT;跑()
{
  VAR TCS =新TaskCompletionSource&LT; TBASE&GT;();
  MethodThatReturnsDerivedTask()。ContinueWith(
      T =&GT; tcs.TryCompleteFromCompletedTask(T)
      TaskContinuationOptions.ExecuteSynchronously);
  返回tcs.Task;
}

或者(如果你不想承担AsyncEx的依赖):

 公共任务&LT; TBASE&GT;跑()
{
  VAR TCS =新TaskCompletionSource&LT; TBASE&GT;();
  。MethodThatReturnsDerivedTask()ContinueWith(T =&GT;
  {
    如果(t.IsFaulted)
      tcs.TrySetException(t.Exception.InnerExceptions);
    否则,如果(t.IsCanceled)
      tcs.TrySetCanceled();
    其他
      tcs.TrySetResult(t.Result);
  },TaskContinuationOptions.ExecuteSynchronously);
  返回tcs.Task;
}

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

However, you can do:

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

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?

解决方案

Does such a method exist?

No.

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

Yes. But it's the easiest solution.

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.

Using Then, your code would look like:

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

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

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

这篇关于如何将任务&LT转换; TDerived&GT;给任务&LT; TBASE&GT ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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