Я работаю над обслуживанием проекта .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(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:
Предложения, которые не требуют от меня создания поточно-ориентированной реализации класса Dict, лучше, так как это будет довольно большой рефакторинг, который не будет очень желанным предложением =)
EDIT2:
Я пытался
lock (((IDictionary)dict).SyncRoot)
Но я получаю
Error 28 Using the generic type 'System.Collections.Generic.IDictionary<TKey,TValue>' requires '2' type arguments
Тогда я попробую это:
lock (((IDictionary<String, int>)dict).SyncRoot)
Ошибка:
Error 28 'System.Collections.Generic.IDictionary<string,int>' does not contain a definition for 'SyncRoot'
ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ (наверное):
Спасибо за все ответы!
Теперь все, что я хочу знать, это. Мой метод (DictAddHelper) будет работать вообще, и если нет, то почему?