我正在努力维护.NET项目,我遇到了一些麻烦,我很乐意和你们分享=)
问题代码:
if( evilDict.Count < 1 ) { foreach (Item item in GetAnotherDict()) if (!evilDict.containsKey(item.name.ToLower().Trim())) evilDict.add(item.name.ToLower().Trim(), item.ID); }
尽管contains() - 检查,我收到一个ArgumentException告诉我已经添加了一个具有相同键的项目.我们只是在生产中遇到这个问题,从未进行过测试,这让我怀疑是并发问题.我想知道的是:
你认为这是并发问题吗?
我如何解决它?
我的修复是否可行(见下文)?
这是我对.NET的第一次尝试,字典通常是问题的根源吗?
这是我的潜在修复,取代了dictionary.add()的东西
protected static void DictAddHelper(Dictionarydict, String key, int value) { lock (dict) { key = key.ToLower().Trim(); if (dict.ContainsKey(key) == false) { try { dict.Add(key, value); } catch (ArgumentException aex) { StringBuilder debugInfo = new StringBuilder(); debugInfo.AppendLine("An argumentException has occured: " + aex.Message); debugInfo.AppendLine("key = " + key); debugInfo.AppendLine("value = " + value); debugInfo.AppendLine("---Dictionary contains---"); foreach (String k in dict.Keys) debugInfo.AppendLine(k + " = " + dict[k]); log.Error(debugInfo, aex); } } } }
编辑:
建议不要求我做一个线程安全的Dict类实现更好,因为这将是一个非常大的重构,不会是一个非常受欢迎的建议=)
EDIT2:
我试过了
lock (((IDictionary)dict).SyncRoot)
但我明白了
Error 28 Using the generic type 'System.Collections.Generic.IDictionary' requires '2' type arguments
然后我试试这个:
lock (((IDictionary)dict).SyncRoot)
错误:
Error 28 'System.Collections.Generic.IDictionary' does not contain a definition for 'SyncRoot'
最终编辑(我猜):
感谢所有的答案!
现在,我想知道的就是这个.我的方法(DictAddHelper)会不会起作用,如果没有,为什么?
如果您怀疑访问字典时出现并发问题,那么您的修复程序将没有任何用处.它将解决您遇到的特定问题,但是如果您同时访问该字典,将来会遇到更多问题.
在修改字典时,请考虑锁定对字典的访问.