我有一个队列,其中有大约 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 秒的时间来完成。
我有以下问题:
- 为什么并行调用比任务花费更多时间?并行调用似乎没有像我想要的那样以并行模式运行。
- 当我使用 Task 时,我会为每个请求创建一个新任务,如果我有 1000 个请求,我最终会创建 1000 个线程还是 CPU 会根据需要负责创建线程?
- Task.WaitAll() 会在程序终止之前等待所有任务完成吗?
最佳答案
您的代码中的问题是 Task.WaitAll()
没有按您的预期工作。您已保存并开始一项任务:
var task = new Task(() => PerformAction(request));
task.Start();
但是您没有保留对每个任务的引用以传递给 WaitAll
。您打算将所有任务保存在一个数组中,然后将该数组传递给 WaitAll
。因此,您的程序使用任务“快速”执行,因为它不等待完成。
您的问题:
请参阅上文了解为什么
Parallel.Invoke
花费更多时间 - 因为它实际运行。但是,您也没有正确使用它。 Parallel.Invoke 采用一系列操作 (Actions[]
) 并尝试并行运行它们。您每次都通过一个 Action 多次调用它。我什至不确定你的代码是如何编译的。我相信你想要的是:Parallel.ForEach(queue.Values, request => PerformAction(request))
您正在为每个请求创建一个新任务,但这不会与线程一对一映射。默认情况下,任务使用 the thread pool .
Task.WaitAll(tasks)
会等待所有tasks
完成。但是,如果您不传递任何东西,它就不会。同样,这不应该像您拥有的那样编译。
关于c# - Parallel.Invoke vs Task 为什么执行时间不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10168578/