2012-06-15 73 views
0

我有一个队列(实际上是3个不同的队列,但我不认为这会有所作为)。队列包含不连续的工作单元。正确处理队列时管理线程的方式

我有一个QueueManager它产生一个新的线程并返回。新线程查看队列,获取一部分工作,然后生成一个新线程来处理它。

我明显希望限制并发线程的数量,并且没有看到任何理由在完成任务后不重用线程。

某些工作需要一段时间才能运行(分钟/小时),而且我读了ThreadPool对于需要几秒钟时间的任何事情都不是一个好的选择。

实际上,我想实现ThreadPool,但有一点控制。

那么......达到此目标的标准,最佳实践方法是什么?

看来我需要(假设队列长度>MaxThreadCount

  • 创造新的工作岗位,直到我打MaxThreadCount
  • 一直等到任何线程完成
  • 从队列中获取下工作,并分配它到线程
  • 重复
  • 如果队列清空,睡一段时间,然后重新检查

(在这种情况下,队列是一个数据库,以便在将项目添加任何情况下 - 我想我就必须轮询)

很多工作涉及检索从远程站点/ API的网页,经常反复。因此,我相信我会比核心拥有更多的线程,因为它们中的大多数都会等待网络。因此,我不认为WaitHandle是合适的,因为它有64个线程的限制。

这显然是一个很常见的模式,所以我认为必须有一个行之有效的实现方式?

如果有人能指出我一个很好的例子,那将是非常好的。

+0

同意TPL答案。 +1如果瓶颈检索远程数据,您可以缓存任何内容吗?你是否重复检索相同的数据? – Paparazzi

+0

@Blam这实际上是一个有趣的问题 - 我可以缓存东西,事实上这样做(至少所有的结果都存储在一个Db中),但大部分信息都是_never_需要两次 - 如果第二次需要,它是以查看源是否已更改,因此虽然我正在记录输出,但除报告目的外,我可能不会再提及它。 – Basic

+0

可能不会帮助你的情况,但一种选择是也将数据存储在字典中,因此你不会像点击数据库那样多。 – Paparazzi

回答

2

使用TPL(任务并行库)。它是专门为此目的而设计的。

http://msdn.microsoft.com/en-us/library/dd460717.aspx

具体来说,这听起来像你应该用TaskScheduler实例,其MaximumConcurrencyLevel已设置为你想要的线程数量创建TaskFactory。然后,不要将您的工作项目放入队列中,请拨打TaskFactory.StartNew。它会为你处理排队工作。

+0

这看起来很有前途,谢谢 - 现在阅读 – Basic

+0

这提出了第二点,我不认为应用 - 我打算使用我的'QueueManager'来更新每个作业完成并存储结果的数据库。我使用EF和多线程EF是一种痛苦。使用TPL,我仍然可以有一个控制点来维护Db状态,还是必须在每个线程中处理它? – Basic

+0

您需要在某个时候处理多个线程。你可以有一个单线程的任务调度程序,但这是有目的的。 –