为什么我们需要使用ContinueWith方法?

18
为什么我们需要 Task.ContinueWith() 方法?我们不能把“后续代码”直接写在 Task 主体中吗?
3个回答

10

Sasha Goldshtein的回答是正确的。有时候你的“ continue”组合代码没有直接访问任务的执行方法,甚至没有设置任务的执行方法。例如,一个想要聚合任务的可插拔系统。

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

考虑可能引发使用TaskCreationOptions.LongRunning的需求。在调度、执行和完成许多数百个进程的并行系统中,任务调度程序正在努力促进有效的处理器亲和性。

如果您处于可以将任务分解为细粒度子任务并链接它们的情况下,则将不再需要使用TaskCreationOptions.LongRunning。简单地说,这将表现更好,因为在只有4个核心可用的环境中安排100个小任务同时完成比安排10个大任务做同样的事情要容易得多。请记住,链接任务不能保证在其前一任务之后立即启动。

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

如果问我,应该在可能的情况下使用ContinueWith(),因为它将帮助您的应用程序扩展。


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

5
任务继续允许您链接一系列任务,链中的每个任务都会跟随另一个任务。
此外,在Task.ContinueWith方法中,您可以异步使用TaskContinuationOptions检查目标任务完成或出现错误时的任务。
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()
);

更多信息请查看这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接