![](/img/trans.png)
[英]Convert Expression<Func<TDerived, out TResult>> to Expression<Func<TBase, out TResult>>
[英]How to convert a Task<TDerived> to a Task<TBase>?
由于 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 在一篇博客文章中对此进行了探讨,我最近将其合并到 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;
}
有这样的方法吗? 仅为此目的使用异步方法是否有任何开销?
没有为此的内置方法,这确实会导致开销。
“最轻量级”的替代方法是使用TaskCompletionSource<T>
为此创建一个新任务。 这可以通过像这样的扩展方法来完成:
static Task<TBase> FromDerived<TBase, TDerived>(this Task<TDerived> task) where TDerived : TBase
{
var tcs = new TaskCompletionSource<TBase>();
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<TDerived>( t => (TDerived)t.Result);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.