I use a System.Runtime.MemoryCache
in a web services integration layer to keep some product lists which are external and slow to retrieve. However, I want to refresh those as they expire to free my callers from waiting on it. For that reason I am prewarming this cache using IIS7.5 and have a RemovedCallback
to reload the data when expired.
However, what happens when the web pool process dies gracefully? MemoryCache is disposable, so it will kick my object out, at which point I'll try to cram a new instance back, whilst putting the entire process on hold. Is there any way for me to safely detect that I should not reload data?
internal class ProductCache {
private static object _lock = new object();
private static string _cid = Guid.NewGuid().ToString();
public static Product[] data
{
get
{
lock (_lock)
{
if (!MemoryCache.Default.Contains(_cid))
{
Product[] p;
try
{
// load data into p
}
catch (System.Exception e)
{
Helper.SafeSendExceptionEmail("Integrator.Caching", e);
throw e;
}
MemoryCache.Default.Add(_cid, p, new CacheItemPolicy()
{
AbsoluteExpiration = DateTimeOffset.Now.AddHours(8),
RemovedCallback = arg =>
{
// query again to force reload
var d = data;
}
});
}
return (Product[])MemoryCache.Default[_cid];
}
}
}
}