I am working on supporting a .NET project, and I am having problems that I will gladly share with you guys =)
Problem Code:
if( evilDict.Count < 1 ) { foreach (Item item in GetAnotherDict()) if (!evilDict.containsKey(item.name.ToLower().Trim())) evilDict.add(item.name.ToLower().Trim(), item.ID); }
Despite the fact that contains () is check, I get an ArgumentException telling me that an element with the same key has already been added. We only got this problem in production, never testing, which makes me suspect a concurrency problem. I am wondering:
- Do you think this is a concurrency problem?
- How to fix it?
- Is my solution viable (see below)?
- This is my first hit in .NET, are dictionaries usually the source of problems?
Here is my potential fix replacing dictionary.add () thing
protected static void DictAddHelper(Dictionary<String, int> dict, 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); } } } }
EDIT:
Suggestions that do not require me to make a thread-safe implementation of the Dict class better, as it would be quite a lot of refactoring, which would not be a very welcome suggestion =)
EDIT2:
I tried
lock (((IDictionary)dict).SyncRoot)
But I get
Error 28 Using the generic type 'System.Collections.Generic.IDictionary<TKey,TValue>' requires '2' type arguments
Then I try this:
lock (((IDictionary<String, int>)dict).SyncRoot)
Mistake:
Error 28 'System.Collections.Generic.IDictionary<string,int>' does not contain a definition for 'SyncRoot'
FINAL EDIT (think):
Thanks for all the answers!
Now, all I want to know is this. Will my method (DictAddHelper) work at all, and if not, why?