Странная проблема со словарем и замками C # - PullRequest
1 голос
/ 17 мая 2011

В данный момент у меня очень странная проблема с блокировкой словаря. У меня есть две разные темы, которые обращаются к словарю, одна из них добавляет некоторые записи, а другая пытается их прочитать. Все хорошо, делая записи, самая странная проблема возникает, когда я пытаюсь извлечь некоторые значения из словаря.

Вот как это выглядит

 lock (myDictionary)
{
 //Add an entry here for a key.
}

// Возрождение

lock(myDictionary)
{

 if (myDictionary.ContainsKey(key))
 myDictionary.TryGetValue(key, out store);
}

Как только поток вводит вышеуказанный код, ключи не найдены. НО если я напишу следующее

lock(myDictionary)
{
  Console.WriteLine(myDicionary.Count)
 if (myDictionary.ContainsKey(key))
   myDictionary.TryGetValue(key, out store);
}

Из ниоткуда я вижу тот же словарь, содержащий ключи, которые не были найдены в предыдущем коде. Теперь вы, ребята, можете поспорить, что произошедшая задержка ввода-вывода вызвала у словаря достаточно времени для сохранения некоторых значений, но у меня нет никаких тайм-аутов или чего-то такого, что заставляет меня терять какую-либо обработку, что это означает, пока словарь не содержит некоторые значения для извлечения следующего шага обработки не произойдет, и моя программа будет ждать, пока не получит некоторые значения. Но, к сожалению, этого не произойдет, если я не поставлю Console.WriteLine ... Кто-нибудь сталкивался с такой ситуацией раньше?

1 Ответ

5 голосов
/ 17 мая 2011

Скорее всего, проблема в коде, который вы не показываете. Тип проблем, которые вы описываете, очень распространен в сценариях с многопоточностью: все сводится к синхронизации, а синхронизация меняется, когда вы слегка меняете код. В вашем конкретном случае значение, к которому вы пытаетесь получить доступ, существует или не существует в зависимости от того, что происходит в других потоках. Просто возможно, что значение еще не было введено или уже было удалено, когда код не может его найти, но присутствует, когда код не может его увидеть.

Невозможно сказать наверняка, не увидев остальную часть вашего кода, особенно ту часть, которая записывает / удаляет в / из коллекции.

Несколько других вещей:

  • вам нужно заблокировать доступ для чтения и записи
  • даже если вы заблокируете доступ для чтения и записи, вы не можете гарантировать наличие определенного объекта, если только вы не используете другой тип синхронизации
  • Как уже говорилось, использование ContainsKey в сочетании с TryGetValue не имеет особого смысла, как вы это написали. «TryGetValue» существует, поэтому вам НЕ нужно вызывать ContainsKey: если значение есть, оно будет немедленно возвращено вам, а если нет, результат вызова метода сообщит вам об этом.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...