我最近需要IProducerConsumerCollection<T>
实施,但如果已达到某个容量,我希望它在TryAdd
上屏蔽,如果它为空则阻止TryTake
。我确信BlockingCollection
实际上是IProducerConsumerCollection<T>
的实现,但意识到事实并非如此。这是为什么?
BlockingCollection
的哪个属性不适合实现IProducerConsumerCollection
接口?
我理解BlockingCollection
是IProducerConsumerCollection
的包装器,但不管我认为它本身应该实现相同的接口。
答案 0 :(得分:0)
直接回答标题中的问题似乎是学术上的,而不是那么有用。 Jon提供了一些见解,说明该特定问题的可能答案可能是什么。但是,让我们试着解决你似乎有的潜在需求......
我最近需要一个IProducerConsumerCollection实现,但是如果达到某个容量,我希望它在TryAdd上阻塞,如果它是空的,则阻止在TryTake上阻塞。
这些是BlockingCollection
已提供的功能。它没有实现IProducerConsumerCollection
的事实根本不是障碍,它没有实现该接口的原因似乎也与您实际陈述的需求相关。
- “如果达到某个容量,我希望它在TryAdd上阻止”
醇>
拥有TryAdd()
方法块没有任何意义。该方法的全部原因是具有非阻塞添加操作(或使用超时阻塞)。即尝试执行添加操作,但可能会失败。
相反,使用允许您传递BlockingCollection
容量值的构造函数初始化int
,然后使用Add()
方法实际向集合添加内容。 Add()
方法将阻塞,直到集合的当前大小小于此容量。
请注意,TryAdd()
方法也尊重收集容量;但它将完整集合视为添加操作的立即失败。这似乎与你想要的完全相反;即阻止直到确定添加操作成功。为此,Add()
方法绝对是使用方法。
- “并在TryTake上阻止,如果它是空的”
醇>
出于同样的原因,TryAdd()
阻止没有意义,TryTake()
阻止也没有意义。
而是调用GetConsumingEnumerable()
并使用返回的对象从集合中检索项目。如果集合已清空,则IEnumerable<T>.MoveNext()
方法将阻止,直到将新项目添加到集合中,或者您调用CompleteAdding()
方法。
如果上述内容无法满足您的需求,那么您应该编辑您的问题以准确解释您想要完成的内容。即使有人给你一个完整,准确的答案来解答你在标题中提出的问题,但这并不能帮助你编写任何真正做某事的代码。恕我直言,你应该更多地关注你正在尝试做的事情,以便我们可以帮助你。