Этот вопрос относится к очень конкретному и распространенному сценарию, в котором словарь используется для кеширования по требованию в многопоточной среде. Чтобы избежать блокировки потока, рекомендуется протестировать существующий элемент кэша вне блокировки синхронизации, но если впоследствии нам нужно добавить элемент, который считается записью в словарь, и поэтому большинство рекомендаций, которые я читал в stackoverflow, это то, что вам необходимо заблокировать чтение, а также запись, потому что внутреннее состояние словаря может быть изменено вызовами add().Является ли словарь <K,V> надежным потоком для одновременного чтения и добавления?
Однако, просматривая Microsoft AjaxControlToolkit (класс scriptObjectBuilder), код фактически выполняет TryGet() вне любых блокировок и блокирует только Add() новые элементы в словаре. Я могу видеть, как это возможно, если ведро, в которое элемент помещается, никогда не изменяется после добавления, но мое подозрение в том, что это неправильно и может быть источником ошибок.
Спасибо.
ОБНОВЛЕНИЕ Выполнение документации .Net Я считаю, что описанный шаблон действительно ошибочен. Однако мне было интересно, поддерживает ли это конкретная реализация словаря и что AjaxControlToolkit полагался на это (что было бы сомнительно). Изучая код в Reflector, я уверен, что это действительно неправильно, метод Dictionary.Resize() перераспределяет количество ведер и перемещает элементы ведра вокруг, поэтому любой поток в середине TryGet() может потенциально работать по нестабильным данным.
ОБНОВЛЕНИЕ Дефект был уже зарегистрирован против AjaxControlToolkit на codeplex. См:
Вы пробовали? клиентские сценарии обычно однопоточные. применяются стандартные оговорки. –
Вы пробовали написать тестовый жгут для этого самостоятельно? Мне было бы интересно узнать, не вызывает ли это проблемы. –
Это код ajax на стороне сервера.Есть синхронизация потоков, потому что она использует статический словарь в местах для кэширования данных. – redcalx