我使用C#的TPL实现了一个生产者 - 消费者模式。该场景描述如下。
我有一个为BlockingCollection生成作业的任务。该系列具有容量限制,例如,最多3个工作。我有两个消费者任务,他们尝试从集合中获取作业并执行它们。我还对生产者和消费者实施取消。对于生产者,当它检测到取消时,它将调用BlockingCollection.CompleteAdding(),它允许消费者完成等待。
现在有可能:
时间1:制作人在集合中放置2个作业;
时间2:两个消费者抓住工作并自己跑步;
时间3:制片人在集合中再放3个工作。由于它符合收集的能力,生产者就睡着了;
时间4:取消发生在两个消费者身上。他们停下来。
现在制片人永远睡不着,因为没有人在这份工作上工作。如何处理消费者的取消,以便他们可以唤醒生产者?
我能想到的是将以下代码放在消费者的取消处理程序中。
lock(BlockingCollection){
if(BlockingCollection.BoundedCapacity == BlockingCollection.Count) BlockingCollection.Take();
}
由于有多个消费者,因此必须锁定该集合。仅当BlockingCollection.BoundedCapacity等于其中的项目数时,才需要额外获取。这个额外的操作将清空集合中的一个插槽,从而触发生产者唤醒,检测取消本身。
这是对的吗?
答案 0 :(得分:1)
我会使用Add
:http://msdn.microsoft.com/en-us/library/dd381879.aspx
当您取消消费者时,您还可以通过同时触发取消令牌或在消费者线程中确保取消生产者。