管理TPL队列

时间:2012-06-19 11:16:07

标签: multithreading .net-4.0 parallel-processing task-parallel-library

我有一项运行各种服务器扫描的服务。有问题的网络可能很庞大(数十万个网络节点)。

该软件的当前版本正在使用我们设计的排队/线程架构,该架构可以工作但效率不高(尤其是因为作业可能会产生不能很好处理的子节点)

V2即将到来,我正在考虑使用TPL。看起来它应该是理想的选择。

我见过this question,答案意味着TPL可以处理的任务没有限制。在我的简单测试中(旋转100,000个任务并将它们交给TPL),TPL很早就开始出现内存异常(足够公平 - 特别是在我的开发盒上)。

扫描时间可变,但是5分钟/任务是一个很好的平均值。

可以想象,对于大型网络的扫描可能需要相当长的时间,即使在功能强大的服务器上也是如此。

我已经有了一个框架,它允许扫描作业(存储在Db中)在多个扫描服务器之间分配,但问题是我应该如何将工作传递给特定服务器上的TPL。 / p>

我是否可以监控TPL队列的大小,如果它低于几百个条目,可以(如果)加满它?这样做有不利之处吗?

我还需要处理需要暂停扫描的情况。通过不向TPL提供工作比通过取消/重置可能已经部分处理的任务更容易做到这一点。

所有初始任务都可以按任何顺序运行。必须在父项开始执行后运行子项,但由于父项产生它们,这应该不是问题。孩子们可以按任何顺序跑步。因此,我目前正在设想将子任务写回Db而不是直接生成TPL。如果需要,这将允许其他服务器“偷窃”。

有没有人以这种方式使用TPL的经验?我需要注意哪些因素?

1 个答案:

答案 0 :(得分:10)

TPL是关于开始小型工作单元并且并行运行它们。关于监视,暂停或限制这项工作

您应该将TPL视为启动“工作”和同步线程的低级工具。

关键点:TPL任务!=逻辑任务。在您的情况下,逻辑任务是扫描任务(“扫描从x到y的ip范围”)。这样的任务应该对应物理任务“System.Threading.Task”,因为这两个是不同的概念。

您需要自己安排,协调,监控和暂停逻辑任务,因为TPL不理解它们而且无法实现。

现在更实际的问题是:

  1. TPL当然可以在没有OOM的情况下启动100k任务。 OOM的发生是因为你的任务代码耗尽了内存。
  2. 扫描网络听起来像是异步代码的一个很好的例子,因为在扫描时你可能会在具有很高程度的并行性的同时等待结果。您可能不希望在您的进程中有500个线程等待网络数据包到达。异步任务非常适合TPL,因为您运行的每个任务都变得纯粹受CPU限制并且很小。这是TPL的最佳选择。