Во-первых, я бы переместил кэширование за пределы вашего класса, содержащее бизнес-логику, и оставил бы вашу бизнес-логику в чистоте и позволил бы вам контролировать кэширование независимо от приложения. Но это не твой вопрос ...
Вам не нужно было упоминать, будете ли вы больше попадать, потенциально рассчитывая вещи несколько раз, пока кэш не станет горячим. Простой подход будет:
if (Cache["key"] == null)
Cache["key"] = obj.processData();
return Cache["key"];
Сам кэш должен гарантировать, что это безопасно.
Если вы хотите явно блокировать во время заполнения кеша, то у вас уже есть семантика для этого в приведенном выше коде, однако я рекомендую это изменение:
if (Cache["key"] == null) {
Synclock blockIfProcessing
if (Cache["key"] == null)
Cache["key"] = obj.processData();
End Synclock
}
return Cache["key"];
По сути, это останавливает блокировку каждого вызова, когда кэш перегревается, и обеспечивает лучшую производительность, а также защищает вас от возможных условий гонки.
Имейте в виду, как только у вас есть две разные блокировки, вы открываете себя для потенциальных тупиков (и это далеко выходит за рамки этой темы).
Найдите решение для кэширования .Net.