对ConcurrentDictionary进行排序是有意义的



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

然后,由于我即将使用它,我深入研究了这个问题,发现这个类实现了IEnumerable,并且这篇文章也证实了可以迭代这种数据。

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

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

希望我已经明确

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

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

来自Dictionary<TKey, TValue> msdn文档:

返回项目的顺序未定义。

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

当你提到"由其接口继承的排序方法"时,你指的是LINQ扩展吗?像OrderBy?如果是这样,这些扩展是纯功能的,总是返回一个新的集合。所以,要回答你的问题"新秩序会持续下去吗?":不,不会。然而,你可以这样使用它:

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

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

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

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

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

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

最新更新