简体   繁体   English

如何使用C#TPL告诉生产者不要等待生产者-消费者模式

[英]How to tell producer to not wait in producer-consumer pattern using C# TPL

I implements a producer-consumer pattern using C#'s TPL. 我使用C#的TPL实现了生产者-消费者模式。 The scenario is described as below. 场景描述如下。

I have a task who produces jobs to a BlockingCollection. 我有一个任务可以为BlockingCollection产生工作。 The collection has a capacity limit, say, 3 jobs maximally. 该馆藏有容量限制,例如最多3个工作。 I have two consumer tasks who try to get jobs from the collection and execute them. 我有两个消费者任务,他们试图从集合中获取工作并执行它们。 I also implement a cancellation to the producer and consumers. 我还对生产者和消费者实行取消。 For producer, when it detects cancellation, it will call BlockingCollection.CompleteAdding(), which allows the consumers to finish waiting. 对于生产者,当检测到取消时,它将调用BlockingCollection.CompleteAdding(),这使使用者可以完成等待。

Now it is possible that: 现在有可能:

Time 1: The producer puts 2 jobs in the collection; 时间1:生产者将2个工作放入集合中;

Time 2: Two consumers grab the jobs and run themselves; 时间2:两个消费者抓住工作并自己经营;

Time 3: The producer puts another 3 jobs in the collection. 时间3:生产者将另外3个工作放到集合中。 Since it meets the capacity of the collection, the producer goes to asleep; 由于它满足了收集的能力,因此生产者进入睡眠状态。

Time 4: The cancellation happens on the two consumers. 时间4:取消发生在两个使用者之间。 They stop. 他们停下来。

Now the producer sleeps forever because no one works on the jobs. 现在,由于没有人在工作上,生产者将永远睡觉。 How to handle the cancellation on consumers so they can sort of wake up the producer? 如何处理消费者的取消,以便他们可以唤醒生产者?

What I can think of is put the below code in the cancellation handler of the consumers. 我能想到的是将以下代码放入使用者的取消处理程序中。

lock(BlockingCollection){
    if(BlockingCollection.BoundedCapacity == BlockingCollection.Count) BlockingCollection.Take();
}

Since there are more than one consumer, it has to lock the collection. 由于有一个以上的消费者,因此必须锁定收藏。 The extra take is only necessary when the BlockingCollection.BoundedCapacity equals to the number of items in it. 仅当BlockingCollection.BoundedCapacity等于其中的项目数时,才需要执行额外操作。 This extra take will empty one slot in the collection and thus trigger the producer to wake up, detect the cancellation itself. 这项额外的操作将清空集合中的一个插槽,从而触发制作者唤醒并检测取消本身。

Is this correct? 这个对吗?

I would use the cancellable overload of Add : http://msdn.microsoft.com/en-us/library/dd381879.aspx 我将使用Add的可取消的重载: http : //msdn.microsoft.com/zh-cn/library/dd381879.aspx

When you cancel the consumers you can also ensure that the producer is cancelled by triggering the cancellation token either at the same time, or in the consumer threads. 当您取消使用方时,还可以通过同时或在使用方线程中触发取消令牌来确保取消了生产方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM