2010-06-02 63 views
1
else if (!registryData.ContainsKey(keyName)) 
{ 
    keyInvolved = new RegistryKy(keyName); 
    lock (registryDataLock) 
    { 
     registryData.Add(keyName, keyInvolved); 
    } 
    processInvolved = new Proces(procInvolved); 
    keyInvolved.addProcessToDict(processInvolved); 
} 

keyName是一個表示註冊表項的字符串。 keyInvolved是實際的註冊表鍵對象。字典/散列圖.........地球究竟發生了什麼?

我被告知,即時添加一個已經存在的密鑰,但我已經檢查過,看它是否在那裏?

+0

也許你可以添加你正在使用的語言? – 2010-06-02 05:57:20

+0

其實你可以把如何定義RegistryKy嗎?我在下面回答,但我真的應該看看RegistryKy的定義以確保! – VoodooChild 2010-06-02 06:05:33

回答

2

這是在黑暗中刺,但事實上,你有lockregistryDataLock對我說,這是多線程。在呼叫ContainsKey之後但在撥打Add之前,另一個線程是否可能將字典添加到字典中?

而且,類似命名的變量,使這個代碼,而難以閱讀...

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

該鎖確實應該在ContainsKey檢查前 – 2010-12-23 05:44:20

+0

這是錯誤的。另一條線可能會進入鎖,你仍然擰。 – 2010-12-23 06:29:28

1

你必須叫ContainsKeyAdd相同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); 
    } 
}