.NET中令人尴尬的可并行化任务

时间:2009-05-07 14:56:21

标签: c# .net parallel-processing

我正在研究一个我需要执行许多令人尴尬的可并行化任务的问题。通过从数据库读取数据来创建任务,但所有任务的集合将超过计算机上的内存量,因此必须创建,处理和处置任务。我想知道什么是解决这个问题的好方法?我在考虑以下两种方法:

  1. 实施同步任务队列。实现从数据库读取数据并将任务放入队列的生产者(任务创建者)(将队列中当前任务的数量限制为常量值,以确保不超过内存量)。有多个消费者进程(任务处理器)从队列中读取任务,处理任务,存储结果并配置任务。这种方法中有多少消费者流程?

  2. 使用.NET Parallel扩展(PLINQ或并行),但我知道必须创建一组任务(我们可以在并行处理时将任务添加到集合中吗?)。因此,我们将创建一批任务 - 一次说N个任务,并处理这些批处理任务并阅读另外N个任务。

  3. 您对这两种方法有何看法?

6 个答案:

答案 0 :(得分:4)

使用带有限队列的ThreadPool,以避免压倒系统。

如果您的每个工作任务都是CPU绑定的,那么最初配置您的系统,以便系统中的线程数等于您的框可以运行的硬件线程数。

如果您的任务不受CPU限制,那么您将不得不尝试使用池大小来获得适合您特定情况的最佳解决方案

您可能需要尝试使用这两种方法来获得最佳配置。

基本上,测试,调整,测试,重复,直到你开心。

答案 1 :(得分:3)

我没有机会实际使用PLINQ,但我知道PLINQ(如vanilla LINQ)基于IEnumerable。因此,我认为这可能是通过C#迭代器块(即yield关键字)实现任务生成器有意义的情况。

假设您没有进行任何必须提前知道整个任务集的操作(例如,排序),我希望PLINQ只会消耗尽可能多的任务。此外,this article引用了一些策略来控制PLINQ如何消耗输入(标题为“处理查询输出”的部分)。

编辑:将PLINQ与ThreadPool进行比较。

根据this MSDN article,有效地将工作分配给线程池并不是微不足道的,即使你“正确”地使用它,使用TPL通常也会表现出更好的性能。

答案 2 :(得分:2)

使用ThreadPool

然后,您可以排队所有内容,并且项目将在线程可用于池时运行,而不会使系统崩溃。唯一的技巧是确定一次运行的最佳线程数。

答案 3 :(得分:1)

听起来像是Microsoft HPC Server 2008的工作。鉴于任务数量太多,您需要某种并行流程管理器。这就是HPC服务器的全部内容。

http://www.microsoft.com/hpc/en/us/default.aspx

答案 4 :(得分:0)

为了给出一个好的答案,我们需要回答几个问题。

每个单独的任务是否可并行化?或者每个任务都是可并行化的主要任务的产物?

此外,它是导致系统内存不足的任务数量,还是每个任务所持有的数据量以及导致系统内存不足的进程?

答案 5 :(得分:-1)

听起来像Windows Workflow Foundation(WF)可能是一件好事。它还可以为您提供一些额外的好处,例如暂停/恢复任务。