Hi all. I'm working on maintenance of a .NET project, and I'm having some troubles which I'll gladly share with you guys =)
The 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 contains()-check, I'm getting an ArgumentException telling me that an item with the same key has already been added. We have only gotten this problem in production, never in testing, which makes me suspect a concurrency problem. What I'm wondering is:
- Do you think it's a concurrency problem?
- How do I fix it?
- Is my fix viable (see below)?
- This is my first stab at .NET, are Dictionaries usually a source of problems?
Here's my potential fix, replacing the 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 don't require me to make a thread-safe implementation of the Dict class are better, since it would be a pretty big refactoring that won't 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)
Error:
Error 28 'System.Collections.Generic.IDictionary<string,int>' does not contain a definition for 'SyncRoot'
FINAL EDIT (I guess):
Thanks for all the answers!
Now, all I want to know is this. Will my method (DictAddHelper) work at all, and if not, why?