Этот вопрос относится к очень специфическому и общему сценарию, в котором словарь используется для кэширования элементов по требованию в многопоточной среде. Чтобы избежать блокировки потоков, предпочтительно тестировать существующий элемент кэша вне блокировки синхронизации, но если впоследствии нам потребуется добавить элемент, это считается записью в словарь, и поэтому большинство советов, которые я читал о stackoverflow, заключается в том, что вам нужно заблокировать как чтение, так и запись, поскольку внутреннее состояние словаря может быть изменено вызовами add ().
Однако, просматривая Microsoft AjaxControlToolkit (класс scriptObjectBuilder), код фактически выполняет TryGet () вне каких-либо блокировок и блокирует только новые элементы Add () в словаре. Я вижу, как это возможно, если корзина, в которую помещается элемент, никогда не изменяется после добавления, но я подозреваю, что это неправильно и может быть источником ошибок.
Спасибо.
UPDATE
Судя по документации .Net, я думаю, что описанный шаблон действительно неверен. Однако мне было интересно, если конкретная реализация Dictionary позволяет это и что AjaxControlToolkit полагался на это (что было бы сомнительно). Изучая код в Reflector, я почти уверен, что это действительно неправильно, метод Dictionary.Resize () перераспределяет количество сегментов и перемещает элементы сегментов, поэтому любой поток в середине TryGet () может потенциально работать на нестабильных данных.
UPDATE
Дефект был уже зарегистрирован в AjaxControlToolkit в кодекплексе. См: