Словарь <K, V> ориентирован на многопотоковое исполнение для одновременного чтения и дополнений?

Этот вопрос касается очень определенного и общего сценария, в котором словарь используется для кэширования по запросу объектов в многопоточной среде. Для предотвращения блокировки потока, предпочтительно протестировать на существующий объект кэша за пределами синхронизирующей блокировки, но если мы впоследствии должны добавить объект затем, это рассчитывает как запись к словарю и поэтому большей части совета, который я читал на stackoverflow, то, что необходимо соединить чтение, а также запись, потому что внутреннее состояние словаря могло бы изменяться вызовами для добавления ().

Однако просматривая AjaxControlToolkit Microsoft (scriptObjectBuilder класс) код действительно на самом деле выполняет TryGet () за пределами любых блокировок и только блокирует для Добавления () новых объектов к словарю. Я вижу, как это могло бы быть возможно, если блок, что объект помещается в никогда изменения, когда-то добавленные, но мое подозрение, - то, что это неправильно и могло бы быть источником ошибок.

Спасибо.

ОБНОВЛЕНИЕ, Идущее документацией .NET, я думаю, что описанный шаблон является действительно неправильным. Однако я задавался вопросом, позволяет ли конкретная реализация Словаря его и что AjaxControlToolkit полагался на это (который будет сомнителен). При исследовании кода в Отражателе я вполне уверен, что это действительно неправильно, Словарь. Измените размер (), метод перераспределяет количество блоков и перемещает объекты блока, таким образом, любой поток посреди TryGet () мог потенциально работать над нестабильными данными.

ОБНОВЛЕНИЕ дефект было уже зарегистрировано против AjaxControlToolkit на codeplex. См.:

6
задан redcalx 5 August 2014 в 12:46
поделиться

3 ответа

Чтобы ответить на мой собственный вопрос после некоторых вложений: Изучив код для Dictionary, я вижу, что метод Dictionary.Resize () перераспределяет количество внутренних сегментов, которые используются для хранения данных, и перераспределяет содержимое сегментов, чтобы элементы находятся в правильном сегменте в зависимости от их хэш-кода. Таким образом, любой поток в середине TryGet () рискует работать с нестабильными данными.

В стороне, возможный подход с низкой блокировкой для класса Dictionary может заключаться в установке блокировки только вокруг метода Resize ().

-1
ответ дан 17 December 2019 в 04:46
поделиться

VB.NET преобразует в месте вызова функции. Список (Integer) по-прежнему хранит целое число (-1, которое является целым значением True)

-121--4222904-

Тесс Феррандес имеет отличную запись в блоге о потоковой обработке проблем с универсальными словарями:

метод FindEntry проходит через словарь, пытаясь найти ключ. Если несколько потоков делают это одновременно, особенно если словарь изменяется в то же время, вы можете оказаться в бесконечном цикле в FindEntry, вызывая высокое поведение ЦП и процесс может зависнуть.

5
ответ дан 17 December 2019 в 04:46
поделиться

Я бы сказал, что это определенно ошибка в AjaxControlToolkit, и рекомендую вам поднять ошибку в CodePlex. Следует использовать ReaderWriteLock (Slim).

1
ответ дан 17 December 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: