为什么我们需要ContinueWith方法?

发布于 2024-11-16 21:28:57 字数 71 浏览 3 评论 0原文

为什么我们需要 Task.ContinueWith() 方法。我们不能在任务主体中编写“继续代码”吗?

Why do we need Task.ContinueWith() method. Cannot we just write that "continuation code" inside Task body?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

骄傲 2024-11-23 21:28:57

萨沙·戈德斯坦的回答是正确的。在某些情况下,您的“继续”组合代码无法直接访问任务的执行方法,甚至无法设置任务的执行方法。例如,想要聚合任务的可插入系统。

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

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

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

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

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

Sasha Goldshtein's answer is correct. There are instances where your 'continue' composition code does not have direct access to, or even set the execution method of a task. A pluggable system that wants to aggregate taks, for example.

However, there is another reason that may apply. Granularity

Consider the requirements that may provoke use of TaskCreationOptions.LongRunning. In a parallel system where many hundreds of processes are being scheduled, executed and completed, the task scheduler is working to promote efficient processor affinity when scheduling tasks.

If you are in a situation where you can break down a task into fine-grained sub tasks and chain them, you will no longer need to use TaskCreationOptions.LongRunning. In simple terms, this will perform better because it is easier to schedules 100 small tasks to finish at the same time, than it is to schedule 10 large tasks to do the same in an environment where only 4 cores are available. Remember that a chained task is not guaranteed to start immediately after it's antecedent.

It is an interesting question and one that only becomes an issue when you want a scalable system.

If you ask me, you should use ContinueWith() where possible as it will help your app scale.

等风来 2024-11-23 21:28:57

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

Sometimes you receive a Task from the outside and want to chain your continuation to it. There are also ways to create a task without an Action (e.g. using TaskCompletionSource).

小姐丶请自重 2024-11-23 21:28:57

任务延续允许您进行任务链,链中的每个任务后面都有一个其他任务。

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

要了解更多信息,请查看 此处

Task continuations allow you to chains of Tasks, each Task in the chain is followed by one other Task

Also in Task.ContinueWith method you can asynchronously check the Task with TaskContinuationOptions when the target Task completes or an error occurs

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()
);

For more information look here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文