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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1792972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 20:52:50  来源:igfitidea点击:

C# HttpRuntime.Cache.Insert() Not holding cached value

c#asp.netcaching

提问by mike

I'm trying to cache a price value using HttpRuntime.Cache.Insert(), but only appears to hold the value for a couple hours or something before clearing it out. What am I doing wrong? I want the value to stay in cache for 3 days.

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

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

采纳答案by IDisposable

Short answer

简答

Your application pool or website is being shutdown too soon. Extend the idle timeout on the site, extend the application pool lifetime for the pool running the site. Raise the memory allocation and request limits.

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

Full answer

完整答案

If you want to know when and why something is being removed from the cache, you need to log the item removal using the CacheItemRemovedCallbackoption on the insertion... Then you can log the reason using the CacheItemRemovedReasonargument. You can thus log the reason as one of the four listed reasons:

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

  1. RemovedThe item is removed from the cache by a Remove method call or by an Insert method call that specified the same key.
  2. ExpiredThe item is removed from the cache because it expired.
  3. UnderusedThe item is removed from the cache because the system removed it to free memory.
  4. DependencyChangedThe item is removed from the cache because the cache dependency associated with it changed.
  1. 已移除 通过 Remove 方法调用或指定相同键的 Insert 方法调用从缓存中移除项目。
  2. 已过期项目已从缓存中删除,因为它已过期。
  3. 未充分利用该项目已从缓存中删除,因为系统将其删除以释放内存。
  4. DependencyChanged该项目已从缓存中删除,因为与其关联的缓存依赖项已更改。

Typically, you will find Expired and Underused being the reasons for things that don't have explict Remove calls made against the cache and don't have dependencies.

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

You will likely find out, while tracing through this fun stuff, that your items are not being expired or underused. Rather, I suspect you'll find that the AppDomain is getting unloaded.

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

One way this can happen due to the web.config (or bin directory, or .aspx, etc.) files getting changed. For more information as to when this occurs see the Application Restartssection of this page. When that happens, the currently pending requests are drained, the cache emptied, and the AppDomain unloaded. You can detect this situation by checking the AppDomain.IsFinalizingForUnloadand logging that during the callback.

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

Another reason for the AppDomain to recycle is when IIS decides to recycle the AppPool for any of the reasons it has been configured with. Examples of that are xxxmemory has been allocated over the lifetime, yyyseconds of runtime for the AppPool, tttscheduled recycle time, or iiiiidle time (no requests incoming). For further details check this article for IIS6or this article for IIS7

AppDomain 回收的另一个原因是当 IIS 决定回收 AppPool 的任何原因时。例如,已在生命周期内分配了xxx内存、AppPool 运行时的yyy秒、ttt计划回收时间或iiii空闲时间(无请求传入)。有关详细信息,请查看IIS6 的这篇文章IIS7 的这篇文章

回答by Josh Pearce

Check the recycle time on your App Pool.

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

回答by John Boker

The docs http://msdn.microsoft.com/en-us/library/4y13wyk9.aspxsay that Cache.NoSlidingExpiration must be used if using an absolute expiration.

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

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

this may not be your problem though, i just found that Cache.NoSlidingExpiration should be the same as TimeSpan.Zero.

不过,这可能不是您的问题,我只是发现 Cache.NoSlidingExpiration 应该与 TimeSpan.Zero 相同。

Next i would check that your app pool isnt expiring and check how much cache you are using. If it's a high traffic site using a lot of memory (ie memory cache) then it will expire cache items as the memory is needed for other things.

接下来,我将检查您的应用程序池是否未过期并检查您使用了多少缓存。如果它是一个使用大量内存(即内存缓存)的高流量站点,那么它会使缓存项目过期,因为其他事情需要内存。

also check the last comment here http://bytes.com/topic/net/answers/717129-c-asp-net-page-cache-getting-removed-too-soonsomeone seems to have found a solution to your problem.

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

回答by Nathan Wheeler

By default, items added to the cache have no set expiration, so this is definitely something outside the cache. I agree with Josh, you should check the recycle time on your App Pool.

默认情况下,添加到缓存中的项目没有设置过期时间,所以这绝对是缓存之外的东西。我同意 Josh,你应该检查你的 App Pool 上的回收时间。

Check out this page to see an example of how you can add a delegate to let you know exactly when your item is being removed from the cache. This might help you in troubleshooting if it's not your App Pool:

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

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

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

~md5sum~

~md5sum~

回答by RickNZ

The Cache object doesn't guarantee that it will hold onto cached objects at all, much less for the full amount of time that you suggest.

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

If you want to more strongly encourage it to do so, you can set CacheItemPriority.High or CacheItemPriority.NotRemovable when you insert an item into the Cache. With the default Normal priority, the runtime has a fairly aggressive policy of letting go of objects when memory pressure increases.

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

On top of that, by default the IIS AppPool will recycle once/day or so, which will clear everything in the Cache.

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