字典和锁C#的奇怪问题

1 c# dictionary locking

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

这是它的样子

 lock (myDictionary)
{
 //Add an entry here for a key.
}
Run Code Online (Sandbox Code Playgroud)

// Retreival

lock(myDictionary)
{

 if (myDictionary.ContainsKey(key))
 myDictionary.TryGetValue(key, out store);
}
Run Code Online (Sandbox Code Playgroud)

一旦线程输入上面的代码,就找不到密钥.但如果我写下面的内容

lock(myDictionary)
{
  Console.WriteLine(myDicionary.Count)
 if (myDictionary.ContainsKey(key))
   myDictionary.TryGetValue(key, out store);
}
Run Code Online (Sandbox Code Playgroud)

我突然想到包含在先前代码中找不到的密钥的相同字典.现在你们可以争辩说发生的事情是I/O延迟导致字典有足够的时间来存储一些值,但是我没有任何超时或者某些东西导致我松开任何处理,这意味着直到字典包含一些值要提取,下一个处理步骤将不会发生,我的程序将等到它获得一些值.但遗憾的是,除非我放置Console.WriteLine,否则不会发生这种情况......任何人之前都遇到过这样的情况?

And*_*ykh 5

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

如果没有看到代码的其余部分,尤其是写入/删除集合的部分,则无法确定.

其他很少的东西:

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