В проекте ASP.NET MVC у нас есть несколько экземпляров данных, которые требуют большого количества ресурсов и времени на сборку. Мы хотим их кэшировать.
MemoryCache
обеспечивает определенный уровень безопасности потоков, но недостаточно, чтобы избежать одновременного запуска нескольких экземпляров кода здания. Вот пример:
var data = cache["key"];
if(data == null)
{
data = buildDataUsingGoodAmountOfResources();
cache["key"] = data;
}
Как вы можете видеть на занятом веб-сайте, сотни потоков могут проходить внутри оператора if одновременно до тех пор, пока данные не будут построены и не сделают операцию здания еще медленнее, излишне потребляя ресурсы сервера.
В MemoryCache существует атомная реализация AddOrGetExisting
, но для нее неверно требуется "значение для установки" вместо "кода для извлечения значения для установки", которое, как я думаю, делает данный метод почти бесполезным.
Мы используем собственные рекламные леса вокруг MemoryCache, чтобы получить это право, однако для этого требуется явное lock
s. Крайне сложно использовать объекты блокировки для каждой записи, и мы обычно избегаем совместного использования объектов блокировки, которые далеки от идеала. Это заставило меня подумать, что причины избежать такой конвенции могут быть преднамеренными.
У меня есть два вопроса:
-
Лучше ли использовать код
lock
для построения? (Возможно, это было более восприимчивым к одному, интересно) -
Каков правильный способ блокировки блокировки для MemoryCache для такой блокировки? Сильное желание использовать строку
key
в качестве объекта блокировки отклоняется в ".NET locking 101".