Когда словарь выдает исключение IndexOutOfRangeException в Add или ContainsKey?
На занятом веб-сайте ASP.NET у меня есть словарь, который действует как кеш, в основном сохраняя пары ключ/значение для последующего поиска.
При высокой нагрузке словарь несколько раз переходит в состояние, где он всегда генерирует исключение IndexOutOfRangeException всякий раз, когда я вызываю метод ContainsKey или Add. Исключение происходит внутри частного метода FindEntry.
Я подозреваю, что это может быть связано с проблемой синхронизации, но я не уверен.
Может ли кто-нибудь сказать мне, при каких обстоятельствах это может случиться? Моя цель - собрать достаточно информации, чтобы я мог воспроизвести проблему в среде dev.
Ответы
Ответ 1
В документации для Dictionary указано:
Любые члены экземпляра не гарантируют безопасность потоков.
Чтобы обеспечить доступ к коллекции для нескольких потоков для чтения и записи, вы должны реализовать свою собственную синхронизацию.
Если вы не синхронизируете доступ к Dictionary
, вы можете получить такие проблемы, как те, которые вы описываете (предположительно, потому что внутреннее состояние больше не действует). Если вы хотите попробовать и воспроизвести это в своей среде разработки, попробуйте создать программу, которая использует несколько потоков для непрерывного чтения и записи с Dictionary
без синхронизации.
Ответ 2
Я согласен, что это почти наверняка проблема синхронизации.
Я не знаю ни одной документации, которая точно описывает, когда и как это может произойти - поведение undefined, если вы используете словарь небезопасным способом.
Для тестирования в вашей среде dev я бы предложил запустить некоторые параллельные потоки, которые случайным образом вставляются, удаляются, обновляются и т.д. в непрерывном цикле (в основном "концентрированная" версия того, что происходит в вашей рабочей среде).
Ответ 3
Здесь в потоковом словаре http://devplanet.com/blogs/brianr/archive/2008/09/26/thread-safe-dictionary-in-net.aspx также проверьте этот вопрос SO.