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