MemoryCache 避免在关机时刷新
MemoryCache avoid refreshing on shutdown
我在 Web 服务集成层中使用 System.Runtime.MemoryCache
来保留一些外部的且检索速度较慢的产品列表。但是,我想在它们过期时刷新它们,以使我的呼叫者免于等待。出于这个原因,我正在使用 IIS7.5 预热此缓存,并有一个 RemovedCallback
在过期时重新加载数据。
但是,当网络池进程正常结束时会发生什么? MemoryCache 是一次性的,因此它会将我的对象踢出,此时我将尝试塞回一个新实例,同时暂停整个过程。有什么方法可以让我安全地检测到我不应该重新加载数据吗?
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];
}
}
}
}
好的,通过挖掘 MemoryCache
和 MemoryCacheStore
来源,似乎缓存是在域卸载时自动处理的,此时它会处理所有存储,进而删除缓存项有 CacheSpecificEviction
个原因。此原因未在其他任何地方使用,因此它必须代表 "I'm dying" 原因(尽管它们在文档中可能更清楚)
public void Dispose()
{
if (Interlocked.Exchange(ref this._disposed, 1) == 0)
{
this._expires.EnableExpirationTimer(false);
ArrayList list = new ArrayList(this._entries.Count);
lock (this._entriesLock)
{
foreach (DictionaryEntry entry in this._entries)
{
MemoryCacheEntry entry2 = entry.Value as MemoryCacheEntry;
list.Add(entry2);
}
foreach (MemoryCacheEntry entry3 in list)
{
MemoryCacheKey key = entry3;
entry3.State = EntryState.RemovingFromCache;
this._entries.Remove(key);
}
}
foreach (MemoryCacheEntry entry4 in list)
{
this.RemoveFromCache(entry4, CacheEntryRemovedReason.CacheSpecificEviction, false);
}
this._insertBlock.Close();
}
}
我在 Web 服务集成层中使用 System.Runtime.MemoryCache
来保留一些外部的且检索速度较慢的产品列表。但是,我想在它们过期时刷新它们,以使我的呼叫者免于等待。出于这个原因,我正在使用 IIS7.5 预热此缓存,并有一个 RemovedCallback
在过期时重新加载数据。
但是,当网络池进程正常结束时会发生什么? MemoryCache 是一次性的,因此它会将我的对象踢出,此时我将尝试塞回一个新实例,同时暂停整个过程。有什么方法可以让我安全地检测到我不应该重新加载数据吗?
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];
}
}
}
}
好的,通过挖掘 MemoryCache
和 MemoryCacheStore
来源,似乎缓存是在域卸载时自动处理的,此时它会处理所有存储,进而删除缓存项有 CacheSpecificEviction
个原因。此原因未在其他任何地方使用,因此它必须代表 "I'm dying" 原因(尽管它们在文档中可能更清楚)
public void Dispose()
{
if (Interlocked.Exchange(ref this._disposed, 1) == 0)
{
this._expires.EnableExpirationTimer(false);
ArrayList list = new ArrayList(this._entries.Count);
lock (this._entriesLock)
{
foreach (DictionaryEntry entry in this._entries)
{
MemoryCacheEntry entry2 = entry.Value as MemoryCacheEntry;
list.Add(entry2);
}
foreach (MemoryCacheEntry entry3 in list)
{
MemoryCacheKey key = entry3;
entry3.State = EntryState.RemovingFromCache;
this._entries.Remove(key);
}
}
foreach (MemoryCacheEntry entry4 in list)
{
this.RemoveFromCache(entry4, CacheEntryRemovedReason.CacheSpecificEviction, false);
}
this._insertBlock.Close();
}
}