字典/ Hashmap .........究竟发生了什么?

时间:2010-06-02 05:54:44

标签: c# dictionary hashmap

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

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

我被告知我正在添加一个已存在的密钥,但我已经检查过它是否存在?

3 个答案:

答案 0 :(得分:2)

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

此外,类似命名的变量使得这段代码难以阅读......

答案 1 :(得分:1)

您必须在同一ContainsKey块内调用Addlock,否则另一个线程可以在您调用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);
    }
}

答案 2 :(得分:-1)

这应该是这样的:

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);
}