Note that there are some explanatory texts on larger screens.

plurals
  1. PORetrieved Dictionary Key Not Found
    primarykey
    data
    text
    <p>I have a <code>SortedDictionary</code> declared like such:</p> <pre><code>SortedDictionary&lt;MyObject,IMyInterface&gt; dict = new SortedDictionary&lt;MyObject,IMyInterface&gt;(); </code></pre> <p>When its populated with values, if I grab any key from the dictionary and then try to reference it immediately after, I get a <code>KeyNotFoundException</code>:</p> <pre><code>MyObject myObj = dict.Keys.First(); var value = dict[myObj]; // This line throws a KeyNotFoundException </code></pre> <p>As I hover over the dictionary (after the error) with the debugger, I can clearly see the same key that I tried to reference is in fact contained in the dictionary. I'm populating the dictionary using a <code>ReadOnlyCollection</code> of <code>MyObjects</code>. Perhaps something odd is happening there? I tried overriding the <code>==</code> operator and <code>Equals</code> methods to get the explicit comparison I wanted, but no such luck. That really shouldn't matter since I'm actually getting a key directly from the <code>Dictionary</code> then querying the <code>Dictionary</code> using that same key. I can't figure out what's causing this. Has anyone ever seen this behavior?</p> <p><strong>EDIT 1</strong></p> <p>In overriding <code>Equals</code> I also overloaded (as MS recommends) <code>GetHashCode</code> as well. Here's the implementation of <code>MyObject</code> for anyone interested:</p> <pre><code>public class MyObject { public string UserName { get; set;} public UInt64 UserID { get; set;} public override bool Equals(object obj) { if (obj == null || GetType()!= obj.GetType()) { return false; } // Return true if the fields match: return this.Equals((MyObject)obj); } public bool Equals(MyObject other) { // Return true if the fields match return this.UserID == other.UserID; } public override int GetHashCode() { return (int)this.UserID; } public static bool operator ==( MyObject a, MyObject b) { // If both are null, or both are same instance, return true. if (System.Object.ReferenceEquals(a, b)) { return true; } // If one is null, but not both, return false. if (((object)a == null) || ((object)b == null)) { return false; } // Return true if the fields match: return a.UserID == b.UserID } public static bool operator !=( MyObject a, MyObject b) { return !(a == b); } } </code></pre> <p>What I noticed from debugging is that if I add a quick watch (after the <code>KeyNotFoundException</code> is thrown) for the expression:</p> <pre><code>dict.ElementAt(0).Key == value; </code></pre> <p>it returns true. How can this be?</p> <p><strong>EDIT 2</strong> So the problem ended up being because <code>SortedDictionary</code> (and <code>Dictionary</code> as well) are not thread-safe. There was a background thread that was performing some operations on the dictionary which seem to be triggering a resort of the collection (adding items to the collection would do this). At the same time, when the dictionary iterated through the values to find my key, the collection was being changed and it was not finding my key even though it was there.</p> <p>Sorry for all of you who asked for code on this one, I'm currently debugging an application that I inherited and I didn't realize this was going on on a timed, background thread. As such, I thought I copied and pasted all the relevant code, but I didn't realize there was another thread running behind everything manipulating the collection.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload