2012-06-01 27 views
7

我有一个递归问题,其中消费者在树的每个级别上执行一些工作,然后需要递归树并在下一级执行相同的工作。当生产者也是消费者时,如何在生产者/消费者模式中使用阻止收集 - 如何结束?

我想使用ConcurrentBag/BlockingCollection等并行运行。在这种情况下,队列的使用者也是队列的生产者!

我的问题是这样的:使用BlockingCollection,我可以写很简单的foreach逻辑出队的项目,排队新的 - 当队列为空,阻塞集合将正确地阻止,并等待新的工作由生产其他消费者之一。

但我怎么知道所有的消费者是否阻止?!

我知道CompleteAdding(),但似乎没有服务,因为唯一一次实际完成的是当所有生产者完成生产并且队列为空时 - 并且由于它们都将被阻塞,有没有人“免费”设置CompleteAdding()。有没有办法检测到这个? (也许一个事件,可以在阻塞时触发,并在解除阻塞时再次触发?)

我可以通过不使用foreach手动处理,但是手动有一段时间(!完成)循环,并使用TryTake,但那么我需要手动睡眠,这似乎是无效的(整个原因有阻塞集合,只有并发集合在第一位!)每次通过循环,如果TryTake是假的,我可以设置一个空闲标志,然后有一个主检查,如果队列是空的,并且所有的线程都是空闲的,设置一个完整的标志,但是再次,这看起来很糟糕。

直觉告诉我有一些方法来使用Blocking Collection来做到这一点,但我不能完全达到目的。

无论如何,人有当消费者是生产者和能够检测何时释放所有块将是真棒

+1

好问题。任何带有外部标志或事件的事情似乎都适合比赛条件。 –

+0

处理器(组合消费者/生产者)是否有很多状态或需要大量资源?你可以重新解决这个问题吗?创建一个Task,每个只执行一次迭代? –

+0

@Damien_The_Unbeliever:是的,我可以做单一的迭代,事实上已经有了这个工作,但我试图使用生产者/消费者模式,因为这是可能在未来被迁移到云的代码,其中工作者角色将是以相同的方式使用Azure队列存储,并且我想保持两个实现之间的整体逻辑尽可能相似。在这种情况下,我将被迫检查工人是否全部闲置以确定排队是否完成,但似乎我应该尽可能高效地在本地 - 也只是想弄清楚:) –

回答

-3

我觉得从MSDN这个链接可以帮助你的良好格局。

Reusable Parallel Data Structures and Algorithms

它暴露了如何处理并发情况下的一些数据结构。

+1

从2007年的数据结构并没有解决我关于4.0并发库的问题 –

+0

所以使用4.0自己实现它们,它只是一个指南,而不是“答案”。 – oarrivi