为什么我们需要ContinueWith方法?

时间:2011-06-24 10:34:46

标签: c# multithreading parallel-processing task-parallel-library conceptual

为什么我们需要Task.ContinueWith()方法。我们不能只在Task体内写下“延续代码”吗?

3 个答案:

答案 0 :(得分:10)

Sasha Goldshtein的回答是正确的。在某些情况下,您的“继续”组合代码无法直接访问,甚至无法设置任务的执行方法。例如,一个想要聚合tak的可插拔系统。

但是,还有另一个原因可能适用。粒度

考虑可能引起TaskCreationOptions.LongRunning使用的要求。在一个并行系统中,正在调度,执行和完成数百个进程,任务调度程序正在努力在调度任务时提高处理器的高效性。

如果您处于将任务分解为细粒度子任务并将其链接的情况下,则不再需要使用TaskCreationOptions.LongRunning。简单来说,这将更好地执行,因为它更容易安排100个小任务同时完成,而不是在仅有4个核心可用的环境中安排10个大型任务执行相同操作。请记住,链接的任务不能保证在它之前立即开始。

这是一个有趣的问题,只有当你想要一个可扩展的系统才会成为一个问题。

如果你问我,你应该尽可能使用ContinueWith(),因为这会有助于你的应用扩展。

答案 1 :(得分:9)

有时你会从外面收到一个任务,并希望将你的延续链接到它。还有一些方法可以在没有Action的情况下创建任务(例如,使用TaskCompletionSource)。

答案 2 :(得分:5)

任务延续允许您进行任务链,链中的每个任务都跟着另一个任务

同样在Task.ContinueWith方法中,当目标Task完成或发生错误时,您可以TaskContinuationOptionsTask异步检查

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