我有一个SortedDictionary
这样的声明:
SortedDictionary<MyObject,IMyInterface> dict = new SortedDictionary<MyObject,IMyInterface>();
当它填充了值时,如果我从字典中获取任何键,然后尝试立即引用它,我会得到KeyNotFoundException
:
MyObject myObj = dict.Keys.First();
var value = dict[myObj]; // This line throws a KeyNotFoundException
当我使用调试器将鼠标悬停在字典上(出现错误后)时,我可以清楚地看到我试图引用的相同键实际上包含在字典中。我正在使用ReadOnlyCollection
of填充字典MyObjects
。也许那里正在发生一些奇怪的事情?我尝试覆盖==
运算符和Equals
方法来获得我想要的显式比较,但没有这样的运气。这真的不重要,因为我实际上是直接从Dictionary
然后查询Dictionary
使用相同的密钥获取密钥。我无法弄清楚是什么原因造成的。有没有人见过这种行为?
编辑 1
在重写Equals
时,我也重载了(如 MS 建议GetHashCode
的那样)。这是MyObject
任何有兴趣的人的实现:
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);
}
}
我从调试中注意到的是,如果我KeyNotFoundException
为表达式添加一个快速监视(在抛出之后):
dict.ElementAt(0).Key == value;
它返回真。怎么会这样?
编辑 2
所以问题最终是因为SortedDictionary
(Dictionary
以及)不是线程安全的。有一个后台线程正在对字典执行一些操作,这似乎触发了集合的使用(将项目添加到集合中会这样做)。同时,当字典遍历值以找到我的键时,集合正在更改,即使它在那里也找不到我的键。
对于所有要求提供此代码的人,我很抱歉,我目前正在调试我继承的应用程序,但我没有意识到这是在定时后台线程上进行的。因此,我以为我复制并粘贴了所有相关代码,但我没有意识到在操纵集合的所有内容背后还有另一个线程在运行。