我想永久地将一个项目添加到缓存中。我使用以下语法:
HttpContext.Current.Cache.Insert(cacheName, c, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
我发现ASP.NET仍然有时会从缓存中删除项目。
关于如何防止这种情况的任何想法(除了删除缓存并使用存储在静态成员中的Dictionary?
马特拉
答案 0 :(得分:22)
您无法阻止ASP.NET从缓存中删除项目(例如,当内存不足时)。
您无法完全阻止某些内容从ASP.NET缓存中删除(即HttpContext.Current.Cache对象),这非常符合设计。
错误!如果使用CacheItemPriority.NotRemovable标记项目,则可以防止将项目从asp.net缓存中删除。每个其他缓存的数据(应用程序,会话等)都以这种方式存储在HttpRuntime缓存中。
人们总是倾向于认为即使这个优先级也不会阻止您的数据过期,但这是由于缺乏适当的文档。我认为这种混淆来自于从缓存中手动删除这样的项目或者由于为其设置的依赖项而被删除的项目。
因此,如果您从未手动删除它,并且从不指定可以删除它的依赖项,那么您可以在appdomain的生命周期内使用您的项目。
答案 1 :(得分:4)
使用Cache.Add()并将缓存优先级设置得非常高(CacheItemPriority.NotRemovable),这将有助于它保留在缓存中。
HttpContext.Current.Cache.Add("key", "your object", null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
System.Web.Caching.CacheItemPriority.NotRemovable
这仍然似乎不能保证它在缓存中,但它也设置得如此之高,它不太可能会......但你仍然需要检查它是否存在并重新缓存,如果不是...... 。 (看起来像intertubes上的一些人不喜欢使用这个高缓存设置...而有些人......取决于你的确切场景我猜...)
public static string GetSpecialObject
{
get
{
object obj = HttpContext.Current.Cache["key"];
if (obj == null)
{
obj = HttpContext.Current.Cache.Add("key",
"I stay in cache as best i can object", // Build Object Function Here
null,
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable,
null);
}
return (string)obj;
}
}
祝你好运
答案 2 :(得分:1)
如果你想永久存储在内存中的东西(即AppDomain的生命周期),那么静态字段(在你的情况下,Dictionary<TKey,TValue>
)是你最好的选择。
CLR将包含类型加载到内存后,Dictionary
将保留在内存中,直到AppDomain卸载为止。
答案 3 :(得分:1)
我的回答不正确。请see here获取正确答案。
您无法阻止ASP.NET从缓存中删除项目(例如,当内存不足时)。
如果您需要存储应用程序整个生命周期的数据,请将其放入ApplicationState集合中,例如:
Application["myData"] = ...;
这类似于SessionState集合,但正如名称所示,它是应用程序范围的。
答案 4 :(得分:1)
你不可能完全阻止从ASP.NET缓存中删除某些东西(即HttpContext.Current.Cache对象),这非常符合设计。
请参阅MSDN文章ASP.NET Caching Overview中名为“自动数据删除”的部分,该部分提供了有关从缓存中删除的项目的最相关信息。
它声明:
ASP.NET可以出于以下原因之一从缓存中删除数据:
- 因为服务器上的内存很低,所以称为清理过程。
- 因为缓存中的项目已过期。
- 因为项目的依赖项发生了变化。
为了帮助您管理缓存项目,ASP.NET可以在从缓存中删除项目时通知您的应用程序。
清理是在内存不足时从缓存中删除项目的过程。如果项目在一段时间内未被访问,或者项目在添加到缓存时被标记为低优先级,则会删除这些项目。 ASP.NET使用CacheItemPriority对象来确定首先清除哪些项。有关更多信息,请参见如何:向缓存添加项目。
正是出于这个原因(清理,如果没有其他的),你永远不能完全依赖你之前放置在缓存中的项目,并使用NoSlidingExpiration和NoAbsoluteExpiration明确标记它,甚至可能将其标记为高优先级item,因为在稍后的某个时间点仍然存在于缓存中。
答案 5 :(得分:0)
您应该准备好处理缓存未命中并根据需要重新加载缓存中的信息。见here
答案 6 :(得分:0)
尝试将CacheItemPriority.NotRemovable选项与:
结合使用<system.web>
<caching>
<cache disableExpiration="true"/>
</caching>
....
</system.web>
此应覆盖machine.config设置。