I have a mysterious situation using a dictionary, where I list the keys from the dictionary, but the dictionary does not contain some keys, which, according to him, contain.
Dictionary<uint, float> dict = GetDictionary(); // Gets values, 6268 pairs foreach(uint key in dict.Keys) { if (!dict.ContainsKey(key)) Console.WriteLine("Wat? "+key); }
The above version will output two of the 6268 keys. There is nothing special about these two keys, both positive values ββare less than Int32.MaxValue (369099203 and 520093968).
A check on the counts shows this:
Console.WriteLine(dict.Count); // 6268 Console.WriteLine(dict.Keys.Count()); // 6268 Console.WriteLine(dict.Keys.Count(dict.Keys.Contains)); // 6266
This is a single-threaded .NET4 code running under the .NET4.5 CLR. Dictionary is vanilla Dictionary<uint, float> ie there is no personalized comparison comparator . I assume there is a hash problem due to the uint / int difference, but should it not be guaranteed that ContainsKey(key) will be true for all keys returned in the dictionary key collection? Especially when you ONLY look at the KeyCollection object, as in the bottom code fragment, the total number and number of contained objects is calculated here, which is similar to the odd behavior of ICollection .
Edit:
As expected, there is a reasonable explanation: the collection was previously modified by two parallel threads during its initialization. When something "sometimes breaks", it is a thread problem and, of course, enough. Access to a dict from multiple threads can apparently violate an internal state sufficient to be semi-synchronized for the remainder of its life, but without causing any exceptions.
I am going to switch to a parallel dictionary and possibly delete this question. Thanks.
source share