为什么 BlockingCollection 没有实现 IProducerConsumerCollection

本文关键字:实现 IProducerConsumerCollection BlockingCollection 为什么 | 更新日期: 2023-09-27 18:37:01

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

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

我知道BlockingCollectionIProducerConsumerCollection的包装器,但无论如何,我认为它本身应该实现相同的接口。

为什么 BlockingCollection 没有实现 IProducerConsumerCollection

从字面上回答问题标题中的问题似乎是学术性的,并不是那么有用。乔恩对这个特定问题的可能答案提供了一些见解。但是,让我们尝试解决您似乎有的潜在需求......

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

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

  1. "我希望它在达到一定容量时阻止 TryAdd"

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

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

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

  1. "如果 TryTake 是空的,则阻止它"

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

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


如果上述内容不能满足您的需求,那么您应该编辑您的问题以准确解释您想要完成的任务。即使有人对你在标题中提出的问题给出了一个完整、准确的答案,这也不会帮助你编写任何实际做某事的代码。恕我直言,您应该更多地关注您要做的事情,以便我们为您提供帮助。