【发布时间】:2016-12-03 01:38:07
【问题描述】:
假设我有两个独立的异步函数(我无法控制)来创建任务对象:
Task A();
Task B();
和其他一些非异步函数
void X();
如何构建一个单独的任务链,按顺序执行所有这些任务并允许附加进一步的延续(将在 X 之后执行)?
如果我这样做:
Task Sequential()
{
return A()
.ContinueWith(t => { B(); })
.ContinueWith(t => { X(); });
}
这不起作用,因为 B 将启动一个新的任务链。如果 B 需要很长时间才能完成,则 X 将首先执行(以及 Sequential 的调用者可能对返回的 Task 进行 ContinueWith 的任何其他操作)。我需要 X 成为单个任务链中的最后一个元素,以 B 任务为先例。
如果我这样做:
Task Sequential()
{
return A()
.ContinueWith(t => { B().ContinueWith(t => { X(); }); });
}
这只能部分解决问题,因为即使 A、B 和 X 现在将按顺序执行,如果调用者执行 Sequential().ContinueWith,则该继续将与 B 和 X 并行执行,而不是在 X 之后执行。
【问题讨论】:
-
Alex 的回答是您想要的方式。但出于您的目的,您要完成的工作需要使用承诺(
TaskCompletionSource<T>服务)。 -
如果你说
A和B是独立的,Task.WaitAll(A(), B()).ContinueWith(t => X())不是一个选项吗? -
@VMAtm,你的意思是
Task.WhenAll。 -
是的,
WhenAll不会阻塞线程。 -
相关 GitHub 问题:Then or ContinueWithResult extension method for Task.