如何将Task 转换为Task ?

由于C#的Task是一个类,你显然无法将Task转换为Task

但是,你可以这样做:

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

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

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

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

这种方法存在吗?

没有。

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

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

请注意,更通用的方法是Task的扩展方法,例如Then 。 Stephen Toub 在博客文章中对此进行了探讨,最近我将其整合到AsyncEx中 。

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

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

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

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

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

 public Task Run() { var tcs = new TaskCompletionSource(); 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; } 

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

没有内置的方法,这确实会导致开销。

“最轻的权重”替代方案是使用TaskCompletionSource为此创建新任务。 这可以通过像这样的扩展方法来完成:

 static Task FromDerived(this Task task) where TDerived : TBase { var tcs = new TaskCompletionSource(); task.ContinueWith(t => tcs.SetResult(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith(t => tcs.SetException(t.Exception.InnerExceptions), TaskContinuationOptions.OnlyOnFaulted); task.ContinueWith(t => tcs.SetCanceled(), TaskContinuationOptions.OnlyOnCanceled); return tcs.Task; } 

你可以试试这个: task.ContinueWith( t => (TDerived)t.Result);