ConcurrentDictionaryОднажды на работе пришлось заниматься рефакторингом
У сервис был как будто бы на рандоме выбран LifeTime, из-за чего синглтоны зависели от скопед сервисов, и вызывали их через провайдер
Однако, загвоздка была в том, что синглтоны должны были быть потокобезопасными, и использовали статические экземпляры примитивов синхронизации
Тогда пришла в голову мысль сделать кеш в духе
ConcurrentDictionary<String, SemaphoreSlim>
Правда, впоследствии выяснилось, что
GetOrAdd не атомарный метод, и делегат фабрики значения может быть вызван несколько разПотому что передаваемый пользователем делегат вызывается за пределами внутренней блокировки словаря
Как это обойти?
Рид Копси (Reed Copsey) предлагает оборачивать значение в
Lazy, поскольку настоящий объект будет создан и останется единственным в момент запроса значения из ленивого контейнераПодробнее в статье 👇
http://reedcopsey.com/2011/01/16/concurrentdictionarytkeytvalue-used-with-lazyt/