我对 MemoryCache (System.Runtime.Caching) 有疑问。关于这个对象的其他问题,我发现在域未处理的异常之后没有缓存任何值。
例外是:
Exception: System.TypeInitializationException
Message: The type initializer for 'System.Web.Util.ExecutionContextUtil' threw an exception.
Trace:
at System.Web.Util.ExecutionContextUtil.RunInNullExecutionContext(Action callback)
at System.Web.Hosting.ObjectCacheHost.System.Runtime.Caching.Hosting.IMemoryCacheManager.UpdateCacheSize(Int64 size, MemoryCache memoryCache)
at System.Runtime.Caching.CacheMemoryMonitor.GetCurrentPressure()
at System.Runtime.Caching.MemoryMonitor.Update()
at System.Runtime.Caching.MemoryCacheStatistics.CacheManagerThread(Int32 minPercent)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading._TimerCallback.PerformTimerCallback(Object state)
Caused by Exception: System.Exception Message: Type 'System.Threading.ExecutionContext' does not have a public property named 'PreAllocatedDefault'.
Trace: at System.Web.Util.ExecutionContextUtil.GetDummyDefaultEC()
at System.Web.Util.ExecutionContextUtil..cctor()
异常似乎在 2 到 5 分钟后抛出。我认为解决这个异常应该可以解决我的问题,因为缓存不会被处理。
问题从昨天 19 小时开始,即使我从 3 个月开始使用它......自 12 天以来,生产没有任何变化。服务器托管在 Azure 上(操作系统为 Windows Server 2008 R2)
编辑 异常处理程序
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e) {
System.Threading.Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Global_UnhandledException);
System.Threading.Thread.GetDomain().DomainUnload += new EventHandler(Global_DomainUnload);
}
}
内存缓存包装器
public abstract class MemoryCacheManager : ICacheManager
{
private MemoryCache MemoryCache;
protected MemoryCacheManager()
{
MemoryCache = new MemoryCache("Common.Utils.MemoryCacheManager");
}
private void ItemRemoved(CacheEntryRemovedArguments arguments)
{
switch (arguments.RemovedReason)
{
case CacheEntryRemovedReason.CacheSpecificEviction:
LogManager.Instance.Log(arguments.CacheItem.Key + " : CacheSpecificEviction");
break;
case CacheEntryRemovedReason.ChangeMonitorChanged:
LogManager.Instance.Log(arguments.CacheItem.Key + " : ChangeMonitorChanged");
break;
case CacheEntryRemovedReason.Evicted:
LogManager.Instance.Log(arguments.CacheItem.Key + " : Evicted");
break;
case CacheEntryRemovedReason.Expired:
LogManager.Instance.Log(arguments.CacheItem.Key + " : Expired");
break;
case CacheEntryRemovedReason.Removed:
LogManager.Instance.Log(arguments.CacheItem.Key + " : Removed");
break;
}
}
#region ICacheManager
public void Add(string key, object value, DateTimeOffset absoluteExpiration)
{
var policy = new CacheItemPolicy { AbsoluteExpiration = absoluteExpiration, RemovedCallback = ItemRemoved };
Add(key, value, policy);
}
public void Add(string key, object value, TimeSpan slidingExpiration)
{
var policy = new CacheItemPolicy { SlidingExpiration = slidingExpiration, RemovedCallback = ItemRemoved };
Add(key, value, policy);
}
private void Add(string key, object value, CacheItemPolicy policy)
{
MemoryCache.Add(key, value, policy);
LogManager.Instance.Info(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss") + " " + key + " : Added");
}
public object Get(string key)
{
return MemoryCache.Get(key);
}
public bool Exist(string key)
{
return MemoryCache.Contains(key);
}
public bool Remove(string key)
{
return MemoryCache.Remove(key) != null;
}
#endregion
}
缓存管理器
public class CacheManager : MemoryCacheManager
{
#region Singleton
private static readonly CacheManager instance = new CacheManager();
// Explicit static constructor to tell C# compiler ot to mark type as beforefieldinit
static CacheManager() { }
private CacheManager()
: base()
{
}
public static CacheManager Instance
{
get
{
return instance;
}
}
#endregion
}
在第一次调用 Global_UnhandledException 后,所有 CacheManager.Instance.Get 都返回 null。
我的问题是:如何避免这个异常?或者如何让内存缓存正常工作