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是实际的注册表项对象。
我被告知我正在添加一个已存在的密钥,但我已经检查过它是否存在?
答案 0 :(得分:2)
这是一个黑暗中的刺,但你lock
registryDataLock
的事实告诉我这是多线程的。在调用ContainsKey
之后但在调用Add
之前,是否有可能另一个线程正在将字符添加到字典中?
此外,类似命名的变量使得这段代码难以阅读......
答案 1 :(得分:1)
您必须在同一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);
}
}
答案 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);
}