【问题标题】:Does BlockingCollection<T> guarantee removal order?BlockingCollection<T> 是否保证删除顺序?
【发布时间】:2011-04-19 00:35:10
【问题描述】:

我在几年前编写的应用程序中有一个有界阻塞队列。让我们说实现不那么出色,但它确实有效。但是,它存在一些性能问题。看起来 .NET 4.0 BlockingCollection&lt;T&gt; 是正确的替代品,但我需要确保它实际上是一个队列。也就是说,如果以单一生产者、单一消费者的方式使用,是否保证严格 FIFO?

文档没有具体说明。 BlockingCollection 主题确实说(在备注中):

BlockingCollection&lt;T&gt; 类似于 传统阻塞队列数据 结构,除了底层 数据存储机制被抽象化 以IProducerConsumerCollection&lt;T&gt; 的身份离开。

但没有明确说明删除的顺序与添加的顺序相同。

有人知道吗?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    嗯,BlockingCollection&lt;T&gt; 确实是为并行工作而设计的,在这种工作中,您有多个同时的“生产者”和一个消费者(使用 GetConsumingEnumerable())。

    在这种情况下,您无法保证插入顺序,因此不指定排序约束。

    话虽如此,BlockingCollection&lt;T&gt; 适用于任何IProducerConsumerCollection&lt;T&gt;(在构造函数中指定)。如果您没有在构造函数中提供一个,则在内部,它将使用ConcurrentQueue&lt;T&gt;。这导致它成为 FIFO,因为它实际上是(内部)一个队列。所以是的,默认情况下,至少在当前的实现中,它将“保证在以单一生产者、单一消费者的方式使用时严格 FIFO”。如果您想强制这样做以备将来验证(因为队列是一个实现细节),只需将其构造为:

    var blockingCollection = new BlockingCollection<MyClass>(new ConcurrentQueue<MyClass>());
    

    这将保证它现在和将来都使用队列(因为队列是一个实现细节)。

    【讨论】:

    • 我不相信GetConsumingEnumerable 的存在意味着该集合适用于多个生产者和单个消费者。诚然,该特定方法似乎是针对单个消费者的,但这当然不会阻止多个消费者。
    • @Jim:没有——但这是其背后的主要动机。多个消费者是通过 AddToAny() 设计的,其中每个相关的 BlockingCollections 都由单个消费者使用。事件名称本身“BlockingCollection”暗示它“阻塞”(在消费者方面)直到添加项目。
    • 您回答了我的直接问题,使我不必自己进行 IDASM。谢谢。
    • 关于指定IProducerConsumerCollection实例的问题;该嵌套集合可以独立使用吗?假设在添加到队列时我不想以任何理由阻止生产者,但我确实想在没有什么可出列的情况下阻止消费者。我可以使用我包装的 ConcurrentQueue Enqueue(),然后使用 BlockingCollection 获取(出队)吗?还是在无限 BlockingCollection 上的 Add() 期间阻塞不是问题?
    • @DaveBlack 枚举顺序取决于底层数据结构。 BlockingCollection 不一定是队列 - 尽管默认值恰好是一个。如果你只有一个生产者线程,你会没事的 - 如果你有多个,没有办法保证你不会“同时”插入 2 个线程,在这种情况下,你没有知道应该枚举这两个项目的顺序的方法,等等。
    【解决方案2】:

    也许自这个问题以来 MSDN 文档已经更新,但它现在明确指出 BlockingCollection 将默认为 FIFO,除非另有指示。

    见: https://msdn.microsoft.com/en-us/library/dd997371(v=vs.110).aspx 或者如果 MS 更改链接 google 'MSDN BlockingCollection Overview'

    NET 框架 4.6 和 4.5

    在该页面上查找“指定集合类型”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 2021-10-04
      相关资源
      最近更新 更多