Parallel.Invoke vs Task为什么执行时间不同?

时间:2012-04-16 04:01:42

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

我有一个队列,里面有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时,对于我创建新任务的每个请求,如果我有1000个请求的请求,我将最终创建1000个线程或CPU将根据需要创建线程吗?
  3. Task.WaitAll()out side会在程序终止之前等待所有任务完成吗?

1 个答案:

答案 0 :(得分:9)

代码中的问题是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完成。但如果你没有通过它,它就不会。同样,这不应该像你一样编译。