【问题标题】:Why do we need ContinueWith method?为什么我们需要 ContinueWith 方法?
【发布时间】:2011-06-24 10:34:46
【问题描述】:

为什么我们需要Task.ContinueWith() 方法。我们不能在任务正文中写那个“延续代码”吗?

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        任务延续允许您创建任务链,链中的每个任务都跟在另一个任务之后

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

        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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-09
          • 2021-02-05
          • 2019-03-10
          • 2023-04-06
          相关资源
          最近更新 更多