【问题标题】:Sorting ConcurrentDictionary makes any sense?对 ConcurrentDictionary 进行排序有意义吗?
【发布时间】:2013-11-29 15:49:59
【问题描述】:

一开始我的想法是“这是一个基于哈希的数据类型,然后它是未排序的”。

然后因为我要使用它,所以我深入研究了这个问题,发现这个类实现了IEnumerable,并且this post确认可以迭代这种数据。

所以,我的问题是:如果我在 ConcurrentDictionary 上使用 foreach,那么我读取元素的顺序是什么?

然后,作为第二个问题,我想知道其接口继承的排序方法是否有任何用途。如果我在ConcurrentDictionary 上调用排序方法,新订单将持续存在(例如对于传入的foreach)?。

希望我已经说清楚了

【问题讨论】:

    标签: c# concurrentdictionary


    【解决方案1】:

    当前的实现对元素的顺序没有任何承诺。 未来的实现可以轻松更改枚举元素的顺序。

    因此,您的代码不应依赖于该顺序。

    来自Dictionary<TKey, TValue>msdn docs

    项目返回的顺序是不确定的。

    (我找不到任何关于 ConcurrentDictionary 的参考资料,但同样的原则也适用。)

    当您提到“由其接口继承的排序方法”时,您是指 LINQ 扩展吗?喜欢OrderBy?如果是这样,这些扩展纯粹是功能性的并且总是返回一个新的集合。所以,回答你的问题“新秩序会持续吗?”:不,不会。但是,您可以像这样使用它:

    foreach(KeyValuePair<T1, T2> kv in dictionary.OrderBy(...))
    {
    
    }
    

    【讨论】:

    • 是的,我指的是 LINQ 扩展,哦,是的,该死,我读得太快了,并不关心返回类型。谢谢你的解释。所以我可以说,只有依赖指向键的有序数据集才能以特定顺序迭代 ConcurrentDictionary。
    【解决方案2】:

    如果我在 ConcurrentDictionary 上使用 foreach,那是我读取元素的顺序?

    您按照它们所属的存储桶的顺序获取它们,如果一个存储桶包含多个项目,则这些项目按照它们被添加的顺序排列。 但正如其他人所说,这是一个你不应该依赖的实现细节。

    我想知道它的接口是否继承了排序方法 有任何用途。如果我调用排序方法 ConcurrentDictionary 新订单将持续存在(例如 传入的foreach)?。

    我假设您指的是OrderBy() 接口上的OrderBy() 扩展方法。没有什么会坚持下去。此方法返回另一个IEnumnerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;。字典保持原样。

    【讨论】:

      【解决方案3】:

      如果你不是特别小心的话,听起来你可能会自找麻烦。正如 dcastro 所提到的,元素的顺序不能保证。一个比较麻烦的问题是一个 ConcurrentDictionary 可以随时被其他线程改变。这意味着即使确保了订单,也没有理由不会错过在您迭代时添加的新项目。除非您知道可以阻止其他线程更改字典,否则迭代它可能不是一个好主意。

      【讨论】:

      • ConcurrentDictionaryGetEnumerator 实现返回字典的快照。有点像它的副本。所以枚举System.Collections.Concurrent命名空间下的所有集合是安全的。
      • 只是为了纠正我之前的评论:查看源代码后,实现没有返回字典的快照-“通过枚举器暴露的内容可能包含在 GetEnumerator 之后对字典所做的修改称为”。但是枚举起来仍然是安全的:“枚举器可以安全地与堆栈的读取和写入同时使用”源代码:goo.gl/sU7d8f
      • 这是保存到枚举器通过,我只是想指出,能够做到这一点可能与想要做到这一点不同。非并行枚举允许您在集合中移动并知道您已经访问了每个项目。并行枚举的问题是项目在枚举的同时发生变化,所以当你到最后你不知道你已经处理了每个元素,甚至你已经处理的任何元素仍然在收藏。
      • 您能描述一下您需要“实时”枚举器的情况吗?我已经多次使用这些并发集合,并且枚举快照从来都不是问题。我实际上认为这是一种非常自然的实现方式——我也会这样做。
      • 实际上,在结束枚举集合时确保没有遗漏项目有什么意义?如果一个项目在 1 纳秒后添加,你无论如何都会错过它。
      猜你喜欢
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 2020-07-08
      • 2018-06-19
      • 2023-03-23
      • 2011-01-13
      • 1970-01-01
      • 2013-11-13
      相关资源
      最近更新 更多