为什么我们需要ContinueWith方法

本文关键字:ContinueWith 方法 我们 为什么 | 更新日期: 2023-09-27 18:00:09

为什么我们需要Task.ContinueWith()方法。难道我们就不能在任务体中写那个"延续代码"吗?

为什么我们需要ContinueWith方法

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

然而,还有另一个原因可能适用。粒度

考虑可能引发使用TaskCreationOptions.LongRunning的需求。在一个调度、执行和完成数百个进程的并行系统中,任务调度器在调度任务时致力于提高高效的处理器相关性。

如果您可以将任务分解为细粒度的子任务并将其链接,那么您将不再需要使用TaskCreationOptions.LongRunning。简单地说,这将执行得更好,因为在只有4个核心可用的环境中,安排100个小任务同时完成比安排10个大任务同时完成更容易。记住,链式任务不能保证在其先行任务之后立即启动。

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

如果你问我,你应该尽可能使用ContinueWith(),因为它将帮助你的应用扩展。

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

任务延续允许您创建任务链,链中的每个任务后面跟着一个其他任务

此外,在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()
);

有关更多信息,请查看此处