【问题标题】:Parallel.Invoke vs Task why exceution time different?Parallel.Invoke vs Task 为什么执行时间不同?
【发布时间】:2012-04-16 04:01:41
【问题描述】:

我有一个队列,里面有大约 144 个项目。每个队列元素都是一个请求。我试图通过尝试并行运行代码来提高处理性能。我调用 performaction(request) 方法。它实例化一个对象并将请求传递给它并执行一个操作。我可以并行运行此操作,因为这些请求是独立的,并且请求的操作结果也彼此独立。 首先我尝试了

foreach(var request in queue.Values)
    Parallel.Invoke(() =>PerformAction(request);

然后我尝试了相同的 foreach。

var task = new Task(() => PerformAction(request));
task.Start();

在foreach之外我有

Task.WaitAll();

当运行程序时,parallel.invoke 需要将近 3 秒才能完成,而 Task 需要将近 0.005 秒才能完成。

我有以下问题:

  1. 为什么并行调用比任务花费更多时间?似乎并行调用没有按照我的意愿在并行模式下运行。
  2. 当我使用 Task 时,我为每个请求创建一个新 Task,如果我有 1000 个请求的请求,我最终会创建 1000 个线程还是 CPU 会根据需要负责创建线程?
  3. Task.WaitAll() 会在程序终止前等待所有任务完成吗?

【问题讨论】:

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


    【解决方案1】:

    您的代码中的问题是Task.WaitAll() 没有按您的预期工作。您已保存并开始了一项任务:

    var task = new Task(() => PerformAction(request));
    task.Start();
    

    但是您没有保留对每个任务的引用以传递给WaitAll。您打算将所有任务保存在一个数组中,然后将该数组传递给WaitAll。因此,您的程序使用任务“快速”执行,因为它没有等待完成。

    您的问题:

    1. 请参阅上文,了解为什么 Parallel.Invoke 需要更多时间 - 因为它确实在运行。但是,您也没有正确使用它。 Parallel.Invoke 采用一系列操作 (Actions[]) 并尝试并行运行它们。您每次都用一个动作多次调用它。我什至不确定你的代码是如何编译的。我相信你想要的是:

      Parallel.ForEach(queue.Values, request => PerformAction(request))
      
    2. 您正在为每个请求创建一个新任务,但这并没有与线程一一对应。默认情况下,任务使用the thread pool

    3. Task.WaitAll(tasks) 会等待所有tasks 完成。但如果你什么都不通过,它就不会。同样,这不应该像你拥有的那样编译。

    【讨论】:

    • 抱歉,是的,我将 TaskWaitAll 的任务列表转换为数组。
    • 该方法被定义为Task.WaitAll(params Task[] tasks) (msdn.microsoft.com/en-us/library/dd270695.aspx),所以Task.WaitAll() 是(出乎意料的)合法的C# 代码,它等待一个空的Task[] 数组。 (尽管事实证明,这实际上并不是 OP 甚至拥有的代码。)
    • @BradleyGrainger 是的,这是我的错误,这使它运行得非常快。一旦我转换并添加了数组列表,它就可以正常工作了。
    猜你喜欢
    • 1970-01-01
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-01
    • 2016-02-06
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    相关资源
    最近更新 更多