2010-06-02 2 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

Возможно, вы можете добавить какой у вас язык? –

+0

На самом деле вы можете указать, как определить RegistryKy, пожалуйста? Я ответил ниже, но я действительно должен посмотреть на определение RegistryKy, чтобы быть уверенным !! – VoodooChild

ответ

2

Это удар в темноте, но тот факт, что у вас есть lock на registryDataLock, говорит мне, что это многопоточность. Возможно ли, что другой поток добавляет ключ в словарь после вызова 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 –

+0

Это неправильно. Еще одна нить могла войти в замок, и вы все еще ввернуты. –

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); 
    } 
} 
Смежные вопросы