Словарь / Hashmap ......... что на земле происходит? - PullRequest
1 голос
/ 02 июня 2010
else if (!registryData.ContainsKey(keyName))
{
    keyInvolved = new RegistryKy(keyName);
    lock (registryDataLock)
    {
        registryData.Add(keyName, keyInvolved);
    }
    processInvolved = new Proces(procInvolved);
    keyInvolved.addProcessToDict(processInvolved);
}

keyName - это строка, представляющая раздел реестра. keyInvolved является фактическим объектом ключа реестра.

Мне говорят, что я добавляю ключ, который уже существует, но я уже проверил, находится ли он там или нет ???

Ответы [ 3 ]

2 голосов
/ 02 июня 2010

Это удар в темноте, но тот факт, что у вас есть lock на registryDataLock, говорит мне, что это многопоточность. Возможно ли, что другой поток добавляет ключ в словарь после вызова ContainsKey, но до вызова Add?

Кроме того, переменные с одинаковыми именами делают этот код довольно трудным для чтения ...

1 голос
/ 23 декабря 2010

Вы должны позвонить ContainsKey и Add в пределах одного и того же блока lock, в противном случае другой поток может добавить ключ между временем, когда вы вызываете 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);
    }
}
0 голосов
/ 02 июня 2010

Это должно быть так:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...