Является ли ConcurrentDictionary поточно-ориентированным, чтобы я мог использовать его для статического кэша? - PullRequest
21 голосов
/ 19 июля 2011

В основном, если я хочу сделать следующее:

public class SomeClass
{
    private static ConcurrentDictionary<..., ...> Cache { get; set; }
}

Позволяет ли это мне избегать использования lock s повсеместно?

Ответы [ 2 ]

31 голосов
/ 19 июля 2011

Да, это потокобезопасно, и да, позволяет избежать использования повсеместных блокировок (что бы это ни значило). Конечно, это обеспечит вам потокобезопасный доступ к данным, хранящимся в этом словаре, но если сами данные не являются поточно-ориентированными, то вам, конечно, нужно синхронизировать доступ к ним. Например, представьте, что вы сохранили в этом кэше List<T>. Теперь thread1 выбирает этот список (потокобезопасным способом, так как параллельный словарь гарантирует вам это), а затем начинает перечисление по этому списку. В то же самое время thread2 выбирает тот же самый список из кэша (потокобезопасным способом, поскольку параллельный словарь гарантирует вам это) и записывает в список (например, добавляет значение). Вывод: если у вас нет синхронизированной нити1, это приведет к проблемам.

Что касается использования его в качестве кеша, то, вероятно, это не очень хорошая идея. Для кеширования я бы порекомендовал вам то, что уже встроено в фреймворк. Такие классы, как, например, MemoryCache . Причина этого заключается в том, что то, что встроено в сборку System.Runtime.Caching, явно построено для кэширования => оно обрабатывает такие вещи, как автоматическое истечение срока действия данных, если у вас заканчивается нехватка памяти, обратные вызовы для кэша элементы истечения срока действия, и вы даже сможете распределить свой кэш по нескольким серверам, используя такие вещи, как memcached, AppFabric, ..., все, о чем вы не могли бы и мечтать, используя параллельный словарь.

3 голосов
/ 19 июля 2011

Возможно, вам все еще придется использовать блокировку так же, как вам может потребоваться транзакция в базе данных. «Параллельная» часть означает, что словарь будет продолжать правильно работать в нескольких потоках.

В параллельную коллекцию встроены TryGetValue и TryRemove, которые подтверждают, что кто-то может удалить элемент первым. Блокировка на уровне детализации встроена, но вам все еще нужно подумать о том, что делать в этих ситуациях. Для кэширования это часто не имеет значения - то есть это идемпотентная операция.

re: кеширование. Я чувствую , что это зависит от того, что вы храните в кеше + что вы делаете с ним. Существуют затраты на кастинг, связанные с использованием объекта. Вероятно, для большинства веб-приложений лучше всего подходит MemCache, как указано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...