Asp.Net何时删除过期的缓存项?

当您将一个项目添加到具有绝对过期日期的System.Web.Caching.Cache时,如下例所示,Asp.Net的行为如何?可以:

>将项目标记为已过期,然后在下次访问尝试时执行CacheItemRemovedCallback?
>从缓存中删除该项目并立即执行CacheItemRemovedCallback?

HttpRuntime.Cache.Insert(key,
                         new object(),
                         null, 
                         DateTime.Now.AddSeconds(seconds), 
                         Cache.NoSlidingExpiration,
                         CacheItemPriority.NotRemovable, 
                         OnCacheRemove);

MSDN似乎表明它立即发生。例如,the “Expiration” section of the “ASP.NET Caching Overview”表示“ASP.NET会在缓存中过期时自动删除项目”。类似地,来自主题“How to: Notify an Application When an Item Is Removed from the Cache”的示例说:“如果在GetReport调用之间超过15秒(示例中的一个方法),ASP.NET将从缓存中删除该报告。

尽管如此,这些都不明确。他们不会说“立即执行回调”,我可以设想他们的作家如何将上面的选项1视为“删除”一个项目。所以我做了一个快速而肮脏的测试,而且,它似乎正在执行 – 即使没有人正在访问我的网站,我也会获得正常的六十秒回调。

尽管如此,我的测试很肮脏,在对Is there a way to run a process every day in a .Net web application without writing a windows service or SQL server jobs的回答的评论中,有人建议Asp.Net实际上会撤销和执行回调,直到某些尝试重新访问缓存为止。

有人可以权威地解决这个问题吗?

Hurray为Reflector

实际上删除了过期的缓存项目(并且调用了回调函数):

1)尝试访问缓存项目。

2)ExpiresBucket.FlushExpiredItems方法运行并获取到项目。这个方法是硬编码的,每20秒执行一次(StackOverflow问题Changing frequency of ASP.NET cache item expiration的接受答案证实了我通过反射器读取这段代码)。然而,这需要额外的资格(为此阅读)。

Asp.Net为服务器上的每个CPU维护一个缓存(我不知道它们是否表示逻辑或物理CPU);每个维护一个CacheExpires实例,它有一个相应的Timer,每隔20秒调用一次FlushExpiredItems方法。

这种方法可以连续地迭代缓存到期数据(一个ExpiresBucket数组数组)的另一个“buckets”集合,依次调用每个bucket的FlushExpiredItems方法。

此方法(ExpiresBucket.FlushExpiredItems)首先迭代桶中的所有缓存项,如果某个项目过期,则会将其过期。然后(我在这里很简单)它迭代它已经标记为过期的项目,并删除它们,执行CacheItemRemovedCallback(实际上,它调用CacheSingle.Remove,调用CacheInternal.DoRemove,然后CacheSingle.UpdateCache,然后CacheEntry.Close,其中实际调用回调)。

所有这些都是顺序发生的,所以有一些机会可能会阻止整个过程并保持(并将缓存项目的过期从指定的到期时间推回)。

然而,在这个时间分辨率下,以二十秒的最小到期间隔,可能阻塞相当长的时间的进程的唯一部分是执行CacheItemRemovedCallbacks。这些任何一个都可以无限期地阻止给定的Timer的FlushExpiredItems线程。 (虽然二十秒钟后,Timer会产生另一个FlushExpiredItems线程。)

总而言之,Asp.Net不保证它将在指定的时间执行回调,但会在某些情况下执行回调。只要有效期间隔超过20秒,只要高速缓存不需要执行耗时的CacheItemRemovedCallbacks(全局 – 任何回调都可能会干扰任何其他回调),它可以按期执行过期回调。对于某些应用来说这将是足够好的,但对于其他应用来说是不够的。

翻译自:https://stackoverflow.com/questions/1434284/when-does-asp-net-remove-expired-cache-items

转载注明原文:Asp.Net何时删除过期的缓存项?