如何将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