MemoryCache Empty:设置后返回null

我有一个使用新的.NET 4 System.Runtime.Caching MemoryCache的MVC 3应用程序的问题。 我注意到,在一个看似不可预测的时间之后,它停止了caching,而且是空的。 考虑一下我从ASP.NET MVC中的一个testing视图直接得到的代码:

MemoryCache.Default.Set("myname","fred", new CacheItemPolicy() { SlidingExpiration = new TimeSpan(0,5,0) }); Response.Write(MemoryCache.Default["myname"]); 

当它工作时,可预测的“fred”被打印出来。 但是,当问题开始发生时,尽pipeSet()MemoryCache.Default["myname"]值为null。 我可以通过在Response.Write()行上设置一个断点来certificate这一点,并使用立即窗口直接设置和读取caching – 它只是不会设置它,并保持空! 唯一能让它再次运行的方法是导致AppDomain重复使用。

有趣的是,当应用程序正常工作时,可以通过打破Response.Write()行并运行MemoryCache.Default.Dispose()来激发问题。 之后,MemoryCache.Default本身不是空(为什么是这样?),但不会保存任何设置。 它不会导致任何错误,但不会保存任何内容。

有人可以validation这个并解释吗? 正如我相信我已经发现,当应用程序停止自己的工作, 一些是处置MemoryCache.Default ,但它不是我!


UPDATE

那么,我现在已经厌倦了这个问题! CLRProfiler似乎不适用于MVC 3. SciTech的CLR工具很好 – RedGate ANTS也是如此。 但他们告诉我的是,MemoryCache对象正在被某种东西处置! 我也certificate了(通过打印时间戳)我的页面上的PartialView应该被caching(由OutputCacheAttribute指定)在几分钟后不会被caching – 它会在每次调用页面时开始刷新。 为了澄清环境,我直接运行在运行Win 7 Ultimate的开发工作站上的IIS 7.5服务器上。 上面提到的内存工具提示我只用了大约9mb的内存。

无奈之下,我已经改变了我的caching代码,首先search环境HttpContext挂钩并使用其cachingfunction,如果可用的话。 早期的testing显示这是可靠的,但感觉像一个讨厌的黑客。

我感觉到MemoryCache和OutputCache不能保证与MVC 3一起工作…

所以,这里有一些消息。 我们研究了这个和YES,这是.NET 4中的一个bug。

好消息是,它已经在.NET 4.5中修复了,所以如果可以的话,请将安装更新到.NET 4.5,而且是稳定的。

另一个好消息是,这个修复已经被移植到了.NET 4中,并将作为QFE(快速修复…一次性修复,您将应用)提供#578315。 它在几天前被回溯/固定,应该尽快出来。 我会尽力得到确切的date,但很快。

另一个好消息是,在QFE之前,.NET 4上有一个解决方法。 解决方法很奇怪,但它可以解锁你。

 using (ExecutionContext.SuppressFlow()) { // Create memory cache instance under disabled execution context flow return new YourCacheThing.GeneralMemoryCache(…); } 

希望这可以帮助。

更新:该修补程序是http://support.microsoft.com/kb/2828843 ,您可以在这里请求它: https : //support.microsoft.com/contactus/emailcontact.aspx?scid=sw;%5BLN%5D; 1422

我们有同样的问题。 我确认一段时间后caching已经处理完了。 这是私人领域_disposed成为1.我相信我没有调用cache.Dispose在我的代码。 但是当我用Reflector查看MemoryCache的代码时,我在构造函数中订阅了两个事件

 domain.DomainUnload += eventHandler; domain.UnhandledException += exceptionEventHandler; private void OnAppDomainUnload(object unusedObject, EventArgs unusedEventArgs) { this.Dispose(); } private void OnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs) { if (!eventArgs.IsTerminating) return; this.Dispose(); } 

这两个事件处理程序都调用Dispose。 可能是在IIS中的一些域回收后,它会导致域卸载,但保持caching在内存中(我不舒服,如果可能的话)。

我一直在经历同样的症状。 我最终导致使用System.Web.Cache类,而不是挂钩到HttpContext.Cache。 它在过去的3天里一直在工作。

另请参阅与同一问题相关的这些链接。

在集成pipe道模式下的WebApp中使用时,MemoryCache会在PollingInterval之后放置

http://connect.microsoft.com/VisualStudio/feedback/details/764911/memorycache-gets-disposed-after-pollinginterval-when-used-in-webapp-in-integrated-pipeline-mode

MemoryCache神奇地处于Disposed状态

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/1233ffb3-6480-431b-94ca-1190f96cf5f6

如果MemoryCache达到内存限制,它将自动驱逐物品。 这可能会发生在你的情况,你有很多项目在caching中?

您可以通过configuration来控制限制。 默认情况下,它根据可用内存进行优化。

当然,调用Dispose将会停止MemoryCache实例的工作,因为它将清理所有可以处理的非托pipe资源。 如果您不打算再使用MemoryCache则只能调用Dispose 。 除了你打电话的时候,我认为这不是你需要解决的问题。