C# HttpRuntime.Cache.Insert()无法保留缓存值

13

我试图使用HttpRuntime.Cache.Insert()缓存一个价格值,但它只能保留几个小时左右的时间就会清除它。我做错了什么?我希望这个值可以在缓存中保持3天。

HttpRuntime.Cache.Insert(CacheName, Price, null, DateTime.Now.AddDays(3), TimeSpan.Zero);  

你如何验证它已经清空? - J.W.
@J.W.:如果条目已被删除/过期,Cache [CacheName] 将为空。 - RickNZ
5个回答

33

简短回答

您的应用程序池或网站关闭得太快了。延长网站的空闲超时时间,扩展运行该网站的池的应用程序池寿命。提高内存分配和请求限制。

完整回答

如果你想知道缓存什么时候以及为什么被移除,需要使用插入操作中的 CacheItemRemovedCallback 选项记录项目的移除。然后你可以使用CacheItemRemovedReason参数记录原因。 因此,您可以将原因记录为以下四种原因之一:

  1. 已删除 通过Remove方法调用或指定相同键的Insert方法调用从缓存中删除该项。
  2. 已过期 缓存条目已过期而从缓存中移除。
  3. 未使用 由于系统将其删除以释放内存,所以从缓存中移除该项。
  4. 依赖项已更改 由于关联的缓存依赖项已更改,因此从缓存中移除该项。

通常,您会发现过期和未使用是不具有显式Remove调用并且没有依赖项的事物的原因。

在跟踪这些有趣的内容时,您很可能会发现您的项目没有过期或未被使用。相反,我怀疑您会发现 AppDomain 被卸载了。

导致这种情况发生的一个原因是web.config(或者bin目录、.aspx等)文件被更改了。欲了解更多信息,请参见此页面中的应用程序重启部分。当发生这种情况时,当前挂起的请求将被清除,缓存将被清空,并且AppDomain将被卸载。您可以通过检查AppDomain.IsFinalizingForUnload并在回调期间记录来检测此情况。

另一个造成AppDomain重新启动的原因是IIS决定为任何其配置的原因重新启动AppPool。例如:已分配的xxx内存超过寿命、AppPool运行时间达到yyy秒、ttt计划重新启动时间或iiii空闲时间(没有请求进入)。有关详细信息,请参阅此文章适用于IIS6此文章适用于IIS7


我曾经遇到过这个问题,无法让iis express停止重启应用程序,奇怪的是这只对mvc项目有影响。我升级到完整版iis后,问题就解决了。 - Jimmy
2
很棒的答案和很棒的用户名! - theycallmemorty
这真是太有帮助了,因为我在运行时以编程方式将节点插入到我的web.config的<databases> </databases>中,这导致缓存过期!如果我没有那么过度地行动,我本可以避免这个问题!跟进:这发生在App_Start期间,当注册所有模块等等...为什么它会影响应用程序在运行时并持续清除缓存呢? - petrosmm

5
缓存对象不能保证始终保留缓存对象,更不用说像您建议的那样完整地保留缓存对象。

如果您想更加强烈地鼓励它这样做,可以在将项目插入缓存时设置CacheItemPriority.High或CacheItemPriority.NotRemovable。使用默认的Normal优先级时,运行时在内存压力增加时会有相当激进的释放对象的策略。

除此之外,默认情况下IIS AppPool每天左右会重新启动一次,这将清除缓存中的所有内容。


4

文档http://msdn.microsoft.com/en-us/library/4y13wyk9.aspx指出,如果使用绝对过期时间,必须使用Cache.NoSlidingExpiration。

HttpRuntime.Cache.Insert(CacheName, Price, null, DateTime.Now.AddDays(3), Cache.NoSlidingExpiration);

虽然这可能不是你的问题,但我发现Cache.NoSlidingExpiration应该与TimeSpan.Zero相同。

接下来,我会检查您的应用程序池是否过期,并检查您使用了多少缓存。如果是高流量站点使用大量内存(即内存缓存),则它将在需要为其他事物提供内存时使缓存项过期。

还要检查此处的最后一条评论http://bytes.com/topic/net/answers/717129-c-asp-net-page-cache-getting-removed-too-soon,有人似乎已经找到了解决方案。


这对我解决一个无关的问题很有帮助。谢谢! - klkitchens

1

检查您的应用程序池的回收时间。


0

默认情况下,添加到缓存中的项目没有设置过期时间,因此这肯定是缓存之外的事情。我同意Josh的看法,你应该检查你的应用程序池的回收时间。

请查看此页面,以查看如何添加委托来让您知道何时从缓存中删除您的项目的示例。如果不是应用程序池的问题,这可能有助于您进行故障排除:

http://msdn.microsoft.com/en-us/library/system.web.caching.cache.add.aspx

~MD5校验和~


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接