我有一个递归问题,其中消费者在树的每个级别上执行一些工作,然后需要递归树并在下一级执行相同的工作。当生产者也是消费者时,如何在生产者/消费者模式中使用阻止收集 - 如何结束?
我想使用ConcurrentBag/BlockingCollection等并行运行。在这种情况下,队列的使用者也是队列的生产者!
我的问题是这样的:使用BlockingCollection,我可以写很简单的foreach逻辑出队的项目,排队新的 - 当队列为空,阻塞集合将正确地阻止,并等待新的工作由生产其他消费者之一。
但我怎么知道所有的消费者是否阻止?!
我知道CompleteAdding(),但似乎没有服务,因为唯一一次实际完成的是当所有生产者完成生产并且队列为空时 - 并且由于它们都将被阻塞,有没有人“免费”设置CompleteAdding()。有没有办法检测到这个? (也许一个事件,可以在阻塞时触发,并在解除阻塞时再次触发?)
我可以通过不使用foreach手动处理,但是手动有一段时间(!完成)循环,并使用TryTake,但那么我需要手动睡眠,这似乎是无效的(整个原因有阻塞集合,只有并发集合在第一位!)每次通过循环,如果TryTake是假的,我可以设置一个空闲标志,然后有一个主检查,如果队列是空的,并且所有的线程都是空闲的,设置一个完整的标志,但是再次,这看起来很糟糕。
直觉告诉我有一些方法来使用Blocking Collection来做到这一点,但我不能完全达到目的。
无论如何,人有当消费者是生产者和能够检测何时释放所有块将是真棒
好问题。任何带有外部标志或事件的事情似乎都适合比赛条件。 –
处理器(组合消费者/生产者)是否有很多状态或需要大量资源?你可以重新解决这个问题吗?创建一个Task,每个只执行一次迭代? –
@Damien_The_Unbeliever:是的,我可以做单一的迭代,事实上已经有了这个工作,但我试图使用生产者/消费者模式,因为这是可能在未来被迁移到云的代码,其中工作者角色将是以相同的方式使用Azure队列存储,并且我想保持两个实现之间的整体逻辑尽可能相似。在这种情况下,我将被迫检查工人是否全部闲置以确定排队是否完成,但似乎我应该尽可能高效地在本地 - 也只是想弄清楚:) –