This is a follow-up to this question, which contains contradictory answers. I am also interested in an answer related to a more recent version of ASP.NET.
My application uses HttpRuntime.Cache
to cache some lists of models that should never expire. They are loaded on application warmup and they are changed quite rarely, but read quite often.
My code is the following:
private void ReportRemovedCallback(string key, object value, CacheItemRemovedReason reason)
{
if (!ApplicationPoolService.IsShuttingDown())
{
var str = $"Removed cached item with key {key} and count {(value as IDictionary)?.Count}, reason {reason}";
LoggingService.Log(LogLevel.Info, str);
}
}
private IDictionary<int, T> ThreadSafeCacheAccessAction(Action<IDictionary<int, T>, bool> action = null)
{
// refresh cache if necessary
var dict = HttpRuntime.Cache[CacheDictKey] as IDictionary<int, T>;
bool invalidated = false;
if (dict == null)
{
lock (CacheLockObject)
{
// getting expiration times from model attribute
var cacheInfo = typeof(T).GetCustomAttributes(typeof(UseInCachedRepositoryAttribute), inherit: true).FirstOrDefault() as UseInCachedRepositoryAttribute;
int absoluteExpiration = cacheInfo?.AbsoluteExpiration ?? Constants.Cache.IndefiniteRetention;
int slidingExpiration = cacheInfo?.SlidingExpiration ?? Constants.Cache.NoSlidingExpiration;
dict = _modelRepository.AllNoTracking.ToList().Where(item => item.PkId != 0).ToDictionary(item => item.PkId, item => item);
HttpRuntime.Cache.Insert(CacheDictKey, dict, dependencies: null,
absoluteExpiration: DateTime.Now.AddMinutes(absoluteExpiration),
slidingExpiration: slidingExpiration <= 0 ? Cache.NoSlidingExpiration : TimeSpan.FromMinutes(slidingExpiration),
priority: CacheItemPriority.NotRemovable,
onRemoveCallback: ReportRemovedCallback);
invalidated = true;
}
}
Based on the documentation provided here, I have also included the following markup within the web.config:
<caching>
<cache disableExpiration="true" disableMemoryCollection="true" />
</caching>
However, from time to time, ReportRemovedCallback
is called for item removal. My feeling is that caching configuration from web.config is ignored (the documentation clearly states it is outdated) and that CacheItemPriority.NotRemovable
means only "a very high priority", not "never remove".
Question: is there a way to convince HttpRuntime.Cache to never remove some items? Or should I consider another caching mechanism?