5

我有一个运行各种服务器扫描的服务。有问题的网络可能非常庞大(数十万个网络节点)。管理TPL队列

该软件的当前版本使用由我们设计的排队/线程体系结构,但其效率并不高(因为作业可能会产生处理不好的儿童)

V2即将到来,我正在考虑使用TPL。它似乎应该是理想的适合。

我见过this question,答案暗示TPL可以处理的任务没有限制。在我的简单测试中(将100000个任务分派给TPL),TPL在相当早的时候就会出现内存异常(足够公平 - 尤其是在我的开发箱中)。

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

正如您所想象的,即使在强壮的服务器上,扫描大型网络也需要相当长的时间。

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

我可以监视TPL队列的大小,并且(如果它低于几百个条目,就可以将它放大)?这样做有缺点吗?

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

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

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

+0

调度数以千计的'任务',其中每个可能需要几分钟可能不是一个好主意。在这种情况下,TPL会反复安排新的“任务”,这对您来说可能不是个好主意。 – svick

+0

我不清楚给定的扫描(运行约5分钟的任务)是否将大部分时间花费在I/O中,等待网络返回的东西或大部分时间用于分析CPU。 你可能会看到的其他一些框架可能更适合这个TPL DataFlow和Reactive Extensions 2.0。 如果您可以给出一些代码来显示给定扫描的外观(至少在某些伪代码中可以找出它的IO/CPU平衡类型),这可能会帮助其他人提供更好的方向。 –

+0

@JamesManning道歉,我应该做得更清楚...> 5分钟的99%等待网络IO – Basic

回答

10

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

您应该将TPL看作是开始“工作”并同步线程的低级工具。

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

您需要自行安排,编排,监控和暂停逻辑任务,因为TPL不理解它们,也无法做到。

现在更多的实际问题:

  1. TPL可以肯定启动100K任务,而无需OOM。发生OOM是因为您的任务代码耗尽内存
  2. 扫描网络对于异步代码来说听起来像是一个很好的例子,因为在扫描时,您可能在等待结果的同时保持高度的并行性。您可能不希望在您的流程中有500个线程全部等待网络数据包到达。异步任务与TPL很好地契合,因为你运行的每个任务都是纯粹的CPU限制和小的。这是TPL的甜蜜点。
+0

谢谢 - 简而言之,我将调整我现有的库并保持调度等等。它只是将实际的线程管理交给TPL。 – Basic

+0

@Basic,实际上是的;-)如果C#5可用于使代码异步相当容易。如果您不在v5上,则可以将“异步interator”模式视为解决方法(http://blogs.msdn.com/b/pfxteam/archive/2009/06/30/9809774.aspx)。 – usr

+0

谢谢你,我已经定位.Net 4.5了 - 为什么不能重写呢?另外,我真的很喜欢MVC中的新ApiController;) – Basic