为什么我们需要Task.ContinueWith()
方法。我们不能只在Task体内写下“延续代码”吗?
答案 0 :(得分:10)
Sasha Goldshtein的回答是正确的。在某些情况下,您的“继续”组合代码无法直接访问,甚至无法设置任务的执行方法。例如,一个想要聚合tak的可插拔系统。
但是,还有另一个原因可能适用。粒度
考虑可能引起TaskCreationOptions.LongRunning使用的要求。在一个并行系统中,正在调度,执行和完成数百个进程,任务调度程序正在努力在调度任务时提高处理器的高效性。
如果您处于将任务分解为细粒度子任务并将其链接的情况下,则不再需要使用TaskCreationOptions.LongRunning。简单来说,这将更好地执行,因为它更容易安排100个小任务同时完成,而不是在仅有4个核心可用的环境中安排10个大型任务执行相同操作。请记住,链接的任务不能保证在它之前立即开始。
这是一个有趣的问题,只有当你想要一个可扩展的系统才会成为一个问题。
如果你问我,你应该尽可能使用ContinueWith(),因为这会有助于你的应用扩展。
答案 1 :(得分:9)
有时你会从外面收到一个任务,并希望将你的延续链接到它。还有一些方法可以在没有Action的情况下创建任务(例如,使用TaskCompletionSource)。
答案 2 :(得分:5)
任务延续允许您进行任务链,链中的每个任务都跟着另一个任务
同样在Task.ContinueWith
方法中,当目标Task
完成或发生错误时,您可以TaskContinuationOptions
与Task
异步检查
Task task = Task.Factory.StartNew
(
() =>
{
//Your action when the task started
}
);
task.ContinueWith
(
_ =>
{
//Your action when the task completed
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent,
TaskScheduler.FromCurrentSynchronizationContext()
);
task.ContinueWith
(
(t) =>
{
//Action when error occured
Exception exception = null;
if (t.Exception.InnerException != null)
{
exception = t.Exception.InnerException;
}
else
{
exception = t.Exception;
}
//You can use this exception
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent,
TaskScheduler.FromCurrentSynchronizationContext()
);
有关详细信息,请查看here