为什么我们需要ContinueWith方法?

Vla*_*ani 18 c# parallel-processing multithreading conceptual task-parallel-library

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

Gus*_*dor 10

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

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

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

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

这是一个有趣的问题,只有在您需要可扩展系统时才会成为问题.

如果你问我,你应该尽可能使用ContinueWith(),因为它可以帮助你扩展应用程序.


Sas*_*ein 9

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


Nav*_*ani 5

任务继续允许您到任务链,链中的每个任务后面跟着另一个任务

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

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()
);
Run Code Online (Sandbox Code Playgroud)

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