字典和锁C#的奇怪问题

时间:2011-05-17 08:16:55

标签: c# dictionary locking

目前我有一个关于锁定字典的非常奇怪的问题。我有两个不同的线程访问字典,一个线程放入一些条目,另一个尝试读取它们。在创建条目时一切都很顺利,当我尝试从字典中提取一些值时,会出现最奇怪的问题。

这是它的样子

 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,否则不会发生这种情况......任何人都面临过这样的情况吗?

1 个答案:

答案 0 :(得分:5)

问题很可能出在您未展示的代码中。您描述的问题类型在多线程场景中非常常见:一切都归结为时序,当您稍微更改代码时,时序也不同。在您的特定情况下,您尝试访问的任何值是否存在取决于其他线程中发生的事件的时间。当代码无法找到它时,很可能该值尚未存在或已被删除,但在代码无法看到它时存在。

如果没有看到代码的其余部分,尤其是从集合中写入/删除的部分,就不可能肯定地说。

很少有其他事情:

  • 您需要锁定读写访问权限
  • 即使您同时锁定了读写访问权限,也无法保证某个对象存在,除非您还使用其他类型的同步
  • 正如其他人所说,将ContainsKeyTryGetValue结合使用并没有多大意义,就像你编写它一样。 'TryGetValue'存在,因此您不需要调用ContainsKey:如果值存在,它将立即返回给您,如果不存在,方法调用的结果将告诉您。