目前我有一个关于锁定字典的非常奇怪的问题。我有两个不同的线程访问字典,一个线程放入一些条目,另一个尝试读取它们。在创建条目时一切都很顺利,当我尝试从字典中提取一些值时,会出现最奇怪的问题。
这是它的样子
lock (myDictionary)
{
//Add an entry here for a key.
}
// Retreival
lock(myDictionary)
{
if (myDictionary.ContainsKey(key))
myDictionary.TryGetValue(key, out store);
}
一旦线程输入上述代码,就找不到密钥。但如果我写下以下
lock(myDictionary)
{
Console.WriteLine(myDicionary.Count)
if (myDictionary.ContainsKey(key))
myDictionary.TryGetValue(key, out store);
}
无处不在,我看到包含在先前代码中找不到的密钥的相同字典。现在你们可以争辩说发生的事情是I / O延迟导致字典有足够的时间来存储一些值,但是我没有任何超时或者某些东西导致我松开任何处理,这意味着直到字典包含一些值要提取,下一个处理步骤将不会发生,我的程序将等到它获得一些值。但不幸的是,除非我放置Console.WriteLine,否则不会发生这种情况......任何人都面临过这样的情况吗?
答案 0 :(得分:5)
问题很可能出在您未展示的代码中。您描述的问题类型在多线程场景中非常常见:一切都归结为时序,当您稍微更改代码时,时序也不同。在您的特定情况下,您尝试访问的任何值是否存在取决于其他线程中发生的事件的时间。当代码无法找到它时,很可能该值尚未存在或已被删除,但在代码无法看到它时存在。
如果没有看到代码的其余部分,尤其是从集合中写入/删除的部分,就不可能肯定地说。
很少有其他事情:
ContainsKey
与TryGetValue
结合使用并没有多大意义,就像你编写它一样。 'TryGetValue'存在,因此您不需要调用ContainsKey:如果值存在,它将立即返回给您,如果不存在,方法调用的结果将告诉您。