C# HttpRuntime.Cache.Insert() 不保存缓存值

Posted

技术标签:

【中文标题】C# HttpRuntime.Cache.Insert() 不保存缓存值【英文标题】:C# HttpRuntime.Cache.Insert() Not holding cached value 【发布时间】:2010-12-20 01:29:25 【问题描述】:

我正在尝试使用 HttpRuntime.Cache.Insert() 缓存价格值,但在清除它之前似乎只保留了几个小时左右的值。我究竟做错了什么?我希望该值在缓存中保留 3 天。

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

【问题讨论】:

你如何确认它已被清除? @J.W. : 如果条目已被删除/过期,则 Cache[CacheName] 将为空。 【参考方案1】:

简答

您的应用程序池或网站过早关闭。延长站点上的空闲超时,延长运行站点的池的应用程序池寿命。提高内存分配和请求限制。

完整答案

如果您想知道从缓存中删除某些内容的时间和原因,您需要在插入时使用CacheItemRemovedCallback 选项记录项目删除...然后您可以使用CacheItemRemovedReason 参数记录原因.因此,您可以将原因记录为列出的四个原因之一:

    Removed 通过 Remove 方法调用或指定相同键的 Insert 方法调用从缓存中删除该项目。 已过期该项目已从缓存中删除,因为它已过期。 未充分使用该项目已从缓存中删除,因为系统将其删除以释放内存。 DependencyChanged 该项目已从缓存中移除,因为与其关联的缓存依赖项已更改。

通常,您会发现 Expired 和 Underused 是没有针对缓存进行显式 Remove 调用并且没有依赖项的原因。

在浏览这些有趣的东西时,您可能会发现您的物品没有过期或未充分使用。相反,我怀疑您会发现 AppDomain 正在卸载。

由于 web.config(或 bin 目录或 .aspx 等)文件发生更改,可能会发生这种情况。有关何时发生这种情况的更多信息,请参阅this page 的应用程序重新启动部分。发生这种情况时,当前挂起的请求被耗尽,缓存被清空,AppDomain 被卸载。您可以通过检查AppDomain.IsFinalizingForUnload 并在回调期间记录该情况来检测这种情况。

AppDomain 回收的另一个原因是当 IIS 出于任何已配置的原因决定回收 AppPool 时。例如,xxx 内存已在生命周期内分配,yyy 秒的 AppPool 运行时间,ttt 计划的回收时间,或 iiii 空闲时间(没有请求传入)。更多详情请查看this article for IIS6 或this article for IIS7

【讨论】:

我遇到了这个问题,无法让 iis express 停止重新启动应用程序,奇怪的是这只是 mvc 项目的问题。我升级到完整的 iis,问题就消失了。 很好的答案和很好的用户名! 这很有帮助,因为我在运行时以编程方式在我的 web.config 中的<databases> </databases> 中插入节点,这导致缓存过期!如果我不采取额外行动,我本可以避免的问题!追问:这发生在 App_Start 期间,同时注册所有模块等等......为什么它会在运行时影响应用程序并继续清除缓存?【参考方案2】:

Cache 对象根本不保证它会保留缓存的对象,更不用说在您建议的全部时间内。

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

最重要的是,默认情况下,IIS AppPool 每天大约会回收一次,这将清除缓存中的所有内容。

【讨论】:

【参考方案3】:

文档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 似乎有人找到了解决您问题的方法。

【讨论】:

这帮助我解决了一个不相关的问题。谢谢!【参考方案4】:

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

【讨论】:

【参考方案5】:

默认情况下,添加到缓存的项目没有设置过期时间,所以这肯定是缓存之外的东西。我同意 Josh 的观点,你应该检查你的应用程序池的回收时间。

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

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

~md5sum~

【讨论】:

以上是关于C# HttpRuntime.Cache.Insert() 不保存缓存值的主要内容,如果未能解决你的问题,请参考以下文章

C#进阶C# 泛型

C#进阶C# 匿名方法

C#进阶C# 多线程

C# 教程

[C#教程01]C# 简介

用 C# 编写 C# 编译器,先有鸡还是先有蛋?