这样的方法存在吗?
不。
仅出于此目的使用异步方法是否有任何开销?
是的。但这是最简单的解决方案。
请注意,更通用的方法是扩展方法,Task
例如Then
. Stephen Toub在一篇博文中对此进行了探讨,我最近将其合并到 AsyncEx中。
使用Then
,您的代码将如下所示:
public Task<TBase> Run()
{
return MethodThatReturnsDerivedTask().Then(x => (TBase)x);
}
另一种开销略少的方法是创建自己的TaskCompletionSource<TBase>
并使用派生结果完成它(TryCompleteFromCompletedTask
在我的 AsyncEx 库中使用):
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;
}