我不知道我是否以错误的方式思考TPL,但是我很难理解如何获得以下内容:
@H_301_2@我有两个功能
所以直到我们得到C#5.0,我可以做ta.ContinueWith(a => …).在这样的情况下,继续本身返回一个任务的UnWrap().
Task<A> getA() { ... } Task<B> getB(A a) { ... }@H_301_2@这似乎经常发生:我可以异步获得一个A.并给定一个A,我可以异步获得一个B. @H_301_2@我不知道在TPL中将这些功能链接在一起的正确方法. @H_301_2@这是一个尝试:
Task<B> Combined() { Task<A> ta = getA(); Task<Task<B>> ttb = ta.ContinueWith(a => getB(a.Result)); return ttb.ContinueWith(x => x.Result.Result); }@H_301_2@ContinueWith是我感到困惑的地方.返回的类型是“双任务”,任务<任务< B>.这在某种程度上对我来说似乎是错误的. @H_301_2@更新2011-09-30: @H_301_2@巧合的是,我发现扩展方法TaskExtensions.Unwrap对任务< Task< T>>给出任务< T>.
所以直到我们得到C#5.0,我可以做ta.ContinueWith(a => …).在这样的情况下,继续本身返回一个任务的UnWrap().
解决方法
您的getB是否必须是返回任务< B>而不是B?
@H_301_2@问题是
ContinueWith
是:
public Task<TNewResult> ContinueWith<TNewResult>( Func<Task<TResult>,TNewResult> continuationFunction,CancellationToken cancellationToken )@H_301_2@所以在你的情况下,因为getB返回任务< B>,所以你传入一个Func<任务< A>任务< B>,所以TNewResult是任务< B>. @H_301_2@如果您可以更改getB,只需返回一个给定A的B,那么可以使用…或者您可以使用:
return ta.ContinueWith(a => getB(a.Result).Result);@H_301_2@那么lambda表达式将是类型,Func< Task< A>,B>所以ContinueWith将返回任务< B>. @H_301_2@编辑:在C#5中你可以很容易地写:
public async Task<B> CombinedAsync() { A a = await getA(); B b = await getB(a); return b; }@H_301_2@…所以这是“只是”一个问题,解决最终的结果.我怀疑它是这样的,但是错误处理:
public Task<B> CombinedAsync() { TaskCompletionSource<B> source = new TaskCompletionSource(); getA().ContinueWith(taskA => { A a = taskA.Result; Task<B> taskB = getB(a); taskB.ContinueWith(t => source.SetResult(t.Result)); }); return source.Task; }@H_301_2@那有意义吗?