管理TPL队列

Bas*_*sic 5 parallel-processing multithreading .net-4.0 task-parallel-library

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

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

V2即将到来,我正在考虑使用TPL.它似乎应该是理想的选择.

我已经看到了这个问题,答案意味着TPL可以处理的任务没有限制.在我的简单测试中(旋转100,000个任务并将它们交给TPL),TPL很早就开始出现Out-Of-Memory异常(足够公平 - 特别是在我的开发盒上).

扫描需要不同的时间长度,但5分钟/任务是一个很好的平均值.

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

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

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

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

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

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

usr*_*usr 11

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

您应该将TPL视为开始"工作"和同步线程的低级工具.

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

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

现在更实际的问题:

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