Question

At first my thought was like "this is an hash-based data type, then it is unsorted".

Then since I was about to use it I examined the matter in depth and found out that this class implements IEnumerable and also this post confirmed that it is possible to iterate over this kind of data.

So, my question is: if I use foreach over a ConcurrentDictionary which is the order I read the elements in?

Then, as a second question, I'd like to know if the sorting methods inherited by its interfaces are of any kind of use. If I call a sorting method over a ConcurrentDictionary the new order will persist (for example for an incoming foreach)?.

Hope I've made myself clear

Was it helpful?

Solution

The current implementation makes no promises whatsoever regarding the order of the elements. A future implementation can easily change the order by which the elements are enumerated.

As such, your code should not depend on that order.

From the Dictionary<TKey, TValue> msdn docs:

The order in which the items are returned is undefined.

(I couldn't find any reference regarding the ConcurrentDictionary, but the same principle applies.)

When you refer to "the sorting methods inherited by its interfaces", do you mean LINQ extensions? Like OrderBy? If so, these extensions are purely functional and always return a new collection. So, to answer your question "the new order will persist?": no, it won't. You can however use it like this:

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

}

OTHER TIPS

if I use foreach over a ConcurrentDictionary which is the order I read the elements in?

You get them in the order of buckets they belong to, and if a bucket contains multiple items, the items are in the order in which they've been added. But as others have said, this is an implementation detail you shouldn't rely on.

I'd like to know if the sorting methods inherited by its interfaces are of any kind of use. If I call a sorting method over a ConcurrentDictionary the new order will persist (for example for an incoming foreach)?.

I assume you're refering to the OrderBy() extension method on the IEnumnerable<KeyValuePair<TKey, TValue>> interface. No nothing will persist. This method returns another IEnumnerable<KeyValuePair<TKey, TValue>>. The dictionary remains as it is.

Sounds like you might be asking for trouble if you aren't particularly careful. As was mentioned by dcastro order of elements is not ensured. A more troublesome issue is that a ConcurrentDictionary can be changed at any time by other threads. This means that even if order was ensured there is no reason why new items being added while you iterate wouldn't be missed. Unless you know you can prevent other threads from changing the dictionary it's probably not a good idea to iterate over it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top