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