为什么BlockingCollection没有实现IProducerConsumerCollection?

时间:2015-01-11 11:00:20

标签: c# producer-consumer blockingcollection

我最近需要IProducerConsumerCollection<T>实施,但如果已达到某个容量,我希望它在TryAdd上屏蔽,如果它为空则阻止TryTake。我确信BlockingCollection实际上是IProducerConsumerCollection<T>的实现,但意识到事实并非如此。这是为什么?

BlockingCollection的哪个属性不适合实现IProducerConsumerCollection接口?

我理解BlockingCollectionIProducerConsumerCollection的包装器,但不管我认为它本身应该实现相同的接口。

1 个答案:

答案 0 :(得分:0)

直接回答标题中的问题似乎是学术上的,而不是那么有用。 Jon提供了一些见解,说明该特定问题的可能答案可能是什么。但是,让我们试着解决你似乎有的潜在需求......

  

我最近需要一个IProducerConsumerCollection实现,但是如果达到某个容量,我希望它在TryAdd上阻塞,如果它是空的,则阻止在TryTake上阻塞。

这些是BlockingCollection已提供的功能。它没有实现IProducerConsumerCollection的事实根本不是障碍,它没有实现该接口的原因似乎也与您实际陈述的需求相关。

  
      
  1. “如果达到某个容量,我希望它在TryAdd上阻止”
  2.   

拥有TryAdd()方法块没有任何意义。该方法的全部原因是具有非阻塞添加操作(或使用超时阻塞)。即尝试执行添加操作,但可能会失败。

相反,使用允许您传递BlockingCollection容量值的构造函数初始化int,然后使用Add()方法实际向集合添加内容。 Add()方法将阻塞,直到集合的当前大小小于此容量。

请注意,TryAdd()方法也尊重收集容量;但它将完整集合视为添加操作的立即失败。这似乎与你想要的完全相反;即阻止直到确定添加操作成功。为此,Add()方法绝对是使用方法。

  
      
  1. “并在TryTake上阻止,如果它是空的”
  2.   

出于同样的原因,TryAdd()阻止没有意义,TryTake()阻止也没有意义。

而是调用GetConsumingEnumerable()并使用返回的对象从集合中检索项目。如果集合已清空,则IEnumerable<T>.MoveNext()方法将阻止,直到将新项目添加到集合中,或者您调用CompleteAdding()方法。


如果上述内容无法满足您的需求,那么您应该编辑您的问题以准确解释您想要完成的内容。即使有人给你一个完整,准确的答案来解答你在标题中提出的问题,但这并不能帮助你编写任何真正做某事的代码。恕我直言,你应该更多地关注你正在尝试做的事情,以便我们可以帮助你。