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

Nai*_*air 2 c# parallel-processing task-parallel-library

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

foreach(var request in queue.Values)
    Parallel.Invoke(() =>PerformAction(request);
Run Code Online (Sandbox Code Playgroud)

然后我尝试了相同的foreach.

var task = new Task(() => PerformAction(request));
task.Start();
Run Code Online (Sandbox Code Playgroud)

在我所拥有的foreach之外

Task.WaitAll();
Run Code Online (Sandbox Code Playgroud)

当运行程序时,parallel.invoke花了将近3秒才完成,而Task几乎完成了0.005秒.

我有以下问题:

  1. 为什么并行调用花费的时间比任务多?似乎并行调用没有按照我想要的并行模式运行.
  2. 当我使用Task时,对于我创建新任务的每个请求,如果我有1000个请求的请求,我将最终创建1000个线程或CPU将根据需要创建线程吗?
  3. Task.WaitAll()out side会在程序终止之前等待所有任务完成吗?

yam*_*men 9

您的代码中的问题是Task.WaitAll()不能按预期工作.您已保存并启动了一项任务:

var task = new Task(() => PerformAction(request));
task.Start();
Run Code Online (Sandbox Code Playgroud)

但是您没有保留对要传递给每个任务的引用WaitAll.您的意思是将所有任务保存在一个数组中,然后将该数组传递给WaitAll.所以你的程序用Tasks执行'fast',因为它不等待完成.

你的问题:

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

    Parallel.ForEach(queue.Values, request => PerformAction(request))
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您正在为每个请求创建一个新任务,但这不会与一个线程一对一地映射.默认情况下,任务使用线程池.

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