如何将任务&LT转换; TDerived&GT;给任务&LT; TBASE&GT ;? [英] How to convert a Task<TDerived> to a Task<TBase>?
问题描述
由于C#的任务是一个类,你显然不能投了任务&LT; TDerived&GT;
到任务&LT; TBASE&GT;
。
不过,你可以这样做:
公共异步任务&LT; TBASE&GT;跑() {
返回等待MethodThatReturnsDerivedTask();
}
有没有一种静态任务的方法我可以打电话获得任务&LT; TDerived&GT;
实例,它本质上只是指向底层的任务,并投下的结果呢?我想是这样的:
公共任务&LT; TBASE&GT;跑() {
返回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 aTask<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 asThen
. 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 (usingTryCompleteFromCompletedTask
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屋!