В принципе, если я хочу сделать следующее:
public class SomeClass
{
private static ConcurrentDictionary<..., ...> Cache { get; set; }
}
Это позволяет мне избежать использования lock
повсюду?
В принципе, если я хочу сделать следующее:
public class SomeClass
{
private static ConcurrentDictionary<..., ...> Cache { get; set; }
}
Это позволяет мне избежать использования lock
повсюду?
Да, это потокобезопасность, и да, это позволяет избежать использования блокировок повсюду (что бы это ни значило). Конечно, это обеспечит вам поточный безопасный доступ к данным, хранящимся в этом словаре, но если сами данные не являются потокобезопасными, вам необходимо, конечно, синхронизировать с ним доступ. Представьте, например, что вы сохранили в этом кеше a List<T>
. Теперь thread1 извлекает этот список (в потоковом режиме, так как параллельный словарь гарантирует вам это), а затем начинает перечислить этот список. Точно так же thread2 извлекает этот же список из кеша (в потокобезопасной манере, поскольку параллельный словарь гарантирует вам это) и записывает в список (например, он добавляет значение). Вывод: если вы не синхронизировали thread1, он попадет в неприятности.
Что касается использования его в качестве кэша, то это, вероятно, не очень хорошая идея. Для кэширования я бы порекомендовал вам то, что уже встроено в структуру. Например, такие классы, как MemoryCache. Причиной этого является то, что встроенная в System.Runtime.Caching
сборка, явная конструкция для кэширования = > она обрабатывает такие вещи, как автоматическое истечение данных, если вы начинаете работающие на низком уровне памяти, обратные вызовы для элементов истечения срока действия кеша, и вы даже сможете распределять кеш на нескольких серверах с помощью таких вещей, как memcached, AppFabric,..., все, чего вы не могли бы мечтать с помощью параллельного словаря.
Вам все равно придется использовать блокировку так же, как вам может потребоваться транзакция в базе данных. "Параллельная" часть означает, что словарь будет продолжать правильно функционировать в нескольких потоках.
В состав параллельной коллекции входят TryGetValue и TryRemove, которые подтверждают, что кто-то может сначала удалить элемент. Блокировка на гранулированном уровне встроена, но вам все равно нужно подумать о том, что делать в этих ситуациях. Для кэширования это часто не имеет значения, т.е. Это идемпотентная операция.
re: кеширование. Я чувствую, что это зависит от того, что вы храните в кеше +, что вы делаете с ним. Существуют затраты на литье, связанные с использованием объекта. Вероятно, для большинства веб-сайтов MemCache лучше подходит, как было предложено выше.