【问题标题】:Dictionary/Hashmap......... what on earth is happening?字典/哈希图…………到底发生了什么?
【发布时间】:2010-06-02 05:54:44
【问题描述】:
else if (!registryData.ContainsKey(keyName))
{
    keyInvolved = new RegistryKy(keyName);
    lock (registryDataLock)
    {
        registryData.Add(keyName, keyInvolved);
    }
    processInvolved = new Proces(procInvolved);
    keyInvolved.addProcessToDict(processInvolved);
}

keyName 是一个表示注册表项的字符串。 keyInvolved 是实际的注册表项对象。

有人告诉我,我添加了一个已经存在的密钥,但我已经检查过它是否在那里???

【问题讨论】:

  • 也许您可以添加您使用的语言?
  • 请问你能把如何定义RegistryKy吗?我在下面回答了,但我真的应该看看 RegistryKy 的定义!!

标签: c# dictionary hashmap


【解决方案1】:

这是在黑暗中的一次尝试,但你在registryDataLock 上有一个lock 的事实告诉我这是多线程的。是否有可能在调用ContainsKey 之后但在调用Add 之前,另一个线程正在将密钥添加到字典中?

另外,名称相似的变量使这段代码很难阅读...

【讨论】:

    【解决方案2】:

    你必须在同一个lock块内调用ContainsKeyAdd,否则另一个线程可以在你调用ContainsKey和你获取锁之间添加密钥。这是一种方法:

    // check to see if the key exists
    else if (!registryData.ContainsKey(keyName))
    {
        bool foundKey;
        // lock the dictionary
        lock (registryDataLock)
        {
            // make sure another thread didn't add the key while waiting on the lock
            if (!(foundKey = registryData.ContainsKey(keyName)))
            {
                keyInvolved = new RegistryKy(keyName);
                registryData.Add(keyName, keyInvolved);
            }
            // release the lock as soon as we're done with registryData
        }
        // now perform operations that need to be done when we've added
        // a key but without holding the registry lock
        if (!foundKey)
        {
            processInvolved = new Proces(procInvolved);
            keyInvolved.addProcessToDict(processInvolved);
        }
    }
    

    【讨论】:

      【解决方案3】:

      应该是这样的:

      else if (!registryData.ContainsKey(kyInvolved))
      {
          //keyInvolved = new RegistryKy(kyInvolved);
          lock (registryDataLock)
          {
              //registryData.Add(kyInvolved, keyInvolved);
              registryData.Add(kyInvolved, new RegistryKy(kyInvolved));
          }
          processInvolved = new Proces(procInvolved);
          keyInvolved.addProcessToDict(processInvolved);
      }
      

      【讨论】:

      • 锁确实应该在 ContainsKey 检查之前
      • 这是错误的。另一个线程可能会进入锁的右侧,但您仍然被拧紧。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多