MemoryCache Empty :设置后返回null

发布于 2024-12-04 12:18:48 字数 1311 浏览 0 评论 0原文

我在使用新的 .NET 4 System.Runtime.Caching MemoryCache 的 MVC 3 应用程序时遇到问题。我注意到,在一段看似不可预测的时间之后,它会停止缓存内容,并且表现得好像它是空的。考虑一下我直接从 ASP.NET MVC 中的测试视图中获取的这段代码:

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

当它工作时,可以预见的是,会打印“fred”。但是,当问题开始发生时,尽管使用了 Set()MemoryCache.Default["myname"] 的值为 null。我可以通过在 Response.Write() 行上设置断点并使用立即窗口直接设置和读取缓存来证明这一点 - 它只是不会设置它并保持为空!让它再次工作的唯一方法是导致 AppDomain 回收。

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

有人可以验证这一点并解释一下吗?正如我相信我已经发现的那样,当应用程序自行停止工作时,有东西正在处置MemoryCache.Default,但不是我!


更新

好吧,我现在厌倦了这个问题! CLRProfiler 似乎不适用于 MVC 3。SciTech 的 CLR 工具很好 - RedGate ANTS 也很好。但他们只告诉我 MemoryCache 对象正在被某物处置!我还证明(通过时间戳打印)页面上应该缓存的 PartialView(由 OutputCacheAttribute 指定)在几分钟后停止缓存 - 每次调用页面时它都会开始刷新。为了澄清环境,我直接在运行 Win 7 Ultimate 的开发工作站上的 IIS 7.5 服务器上运行。上面提到的内存工具表明,就游戏中的对象而言,我只使用了大约 9mb 的内存。

无奈之下,我更改了缓存代码,首先搜索环境 HttpContext 来挂钩并使用其缓存功能(如果可用)。早期测试表明这是可靠的,但感觉像是一个令人讨厌的黑客攻击。

我感觉 MemoryCache 和 OutputCache 不保证与 MVC 3 一起使用...

I have a problem with an MVC 3 application that is using the new .NET 4 System.Runtime.Caching MemoryCache. I notice that after a seemingly unpredictable time, it stops caching stuff, and acts like it's empty. Consider this bit of code that I took straight from a test View in ASP.NET MVC:

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

When it's working, predictably "fred" gets printed. However, when the problem starts to occur, despite the Set(), the value of MemoryCache.Default["myname"] is null. I can prove this by setting a breakpoint on the Response.Write() line and directly setting and reading from the cache using the Immediate Window - It just won't set it and stays null! The only way to get it working again then is to cause an AppDomain recycle.

Intriguingly I can provoke the problem into occurring when the app is working normally by breaking on the Response.Write() line and running MemoryCache.Default.Dispose(). After that, MemoryCache.Default is not null itself (why is this?), but won't save anything set on it. It doesn't cause any errors, but just won't save anything.

Can anybody verify this and explain? As I believe I have discovered, when the app stops working on its own, something is Disposing MemoryCache.Default, but it's not me!


UPDATE

Well, I'm sick of this prob now! CLRProfiler doesn't seem to work with MVC 3. SciTech's CLR tool was good - so was RedGate ANTS. But all they told me was that the MemoryCache object is being disposed by something! I also proved (via a timestamp print) that a PartialView on my page that should be cached (specified by OutputCacheAttribute) stops being cached after a few minutes - it starts refreshing with every call to the page. Just to clarify the environment, I am running directly on the IIS 7.5 server on my development workstation running Win 7 Ultimate. The memory tools mentioned above suggest I am only using about 9mb of memory in terms of objects in play.

In desperation I have changed my caching code to first search for an ambient HttpContext to hook onto and use its Caching functionality, if one's available. Early tests show this is reliable, but it feels like a nasty hack.

Am getting the feeling that MemoryCache and OutputCache aren't warranted to work with MVC 3...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

§对你不离不弃 2024-12-11 12:18:49

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

在集成管道模式下的 WebApp 中使用时,MemoryCache 在 PollingInterval 之后被释放

MemoryCache 神奇地进入 Dispose 状态

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

See also these links related to the same problem.

MemoryCache gets disposed after PollingInterval when used in WebApp in Integrated Pipeline mode

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

MemoryCache get in Disposed state Magically

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

你的背包 2024-12-11 12:18:49

如果达到内存限制,MemoryCache 将自动驱逐项目。您的情况可能会发生这种情况,您的缓存中是否有很多项目?

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

当然,调用 Dispose 会停止 MemoryCache 实例的工作,因为它将清理所有准备处置的非托管资源。仅当您不再打算使用 MemoryCache 时,才应该调用 Dispose。我认为这对于您的情况来说不是必要的问题,除非您调用它。

The MemoryCache will automatically evict items if it hits it's memory limit. This could be happening in your case, do you have a lot of items in the cache?

You can control the limits with configuration. By default it optimises based on the available memory.

Certainly calling Dispose will stop the MemoryCache instance working as it will clean up all unmanaged resources ready for disposal. You should only call Dispose if you do not intend to use the MemoryCache any more. I don't think this is necessary the problem in your case, other than when you call it.

盛装女皇 2024-12-11 12:18:48

所以,这里有一些消息。我们对此进行了调查,是的,这是 .NET 4 中的一个错误。

好消息是它已在 .NET 4.5 中修复,因此如果可以的话,将安装更新到 .NET 4.5,这样就可以了。

另一个好消息是,此修复已向后移植到 .NET 4,并将作为 QFE(快速修复...您将应用的一次性修复)提供#578315。它几天前才被向后移植/修复,应该尽快发布。我会试着确定一个确切的日期,但很快了。

另一个好消息是,在 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

So, here's some news. We looked into this and YES, this is a bug in .NET 4.

The good news is that it was fixed in .NET 4.5, so if you can, update your installation to .NET 4.5 and you're solid.

The other good news it that this fix has been back-ported to .NET 4 and will be available as a QFE (Quick Fix...a one off fix you'll apply) #578315. It was backported/fixed just days ago and it should be out ASAP. I'll try to get an exact date, but it's soon.

The other other good news is that there's a workaround for this on .NET 4 before the QFE. The workaround is weird, but it could unblock you.

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

Hope this helps.

UPDATE: The Hotfix is http://support.microsoft.com/kb/2828843 and you can request it here: https://support.microsoft.com/contactus/emailcontact.aspx?scid=sw;%5BLN%5D;1422

ま昔日黯然 2024-12-11 12:18:48

我们有同样的问题。我确认在一段时间后缓存被释放。它的私有字段 _dispose 变成了 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 中进行一些域回收后,它会导致域卸载,但将缓存保留在内存中(如果可能的话,我不确定)。

We have the same problem. I confirm that after some period of time cache became disposed. It's private field _disposed became 1. I am sure that I don't have call to cache.Dispose in my code. But when I looked at code of MemoryCache with Reflector I saw, that in constructor it subscribes on two events

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();
}

Both of these event handlers have call to Dispose. May be after some domain recycling in IIS it causes domain unload, but keeps cache in memory(i'am not shure if it is possible).

情徒 2024-12-11 12:18:48

我也经历过完全相同的症状。我最终决定使用 System.Web.Cache 类并挂钩到 HttpContext.Cache。过去 3 天一直运行良好。

I have been experiencing the exact same symptoms. I have finally resulted to using the System.Web.Cache class instead and hooking into HttpContext.Cache. It has been working perfectly for the last 3 days..

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文