Подтвердить что ты не робот

Является ли ConcurrentDictionary потокобезопасным до такой степени, что я могу использовать его для статического кеша?

В принципе, если я хочу сделать следующее:

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

Это позволяет мне избежать использования lock повсюду?

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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