ASP.net 缓存绝对过期不起作用
Posted
技术标签:
【中文标题】ASP.net 缓存绝对过期不起作用【英文标题】:ASP.net Cache Absolute Expiration not working 【发布时间】:2011-08-19 14:58:28 【问题描述】:我在 HttpContext.Cache 中存储一个整数值,其绝对过期时间为 5 分钟后。但是,在等待 6 分钟(或更长时间)后,整数值仍在缓存中(即,即使绝对过期已经过去,它也不会被删除)。这是我正在使用的代码:
public void UpdateCountFor(string remoteIp)
// only returns true the first time its run
// after that the value is still in the Cache
// even after the absolute expiration has passed
// so after that this keeps returning false
if (HttpContext.Current.Cache[remoteIp] == null)
// nothing for this ip in the cache so add the ip as a key with a value of 1
var expireDate = DateTime.Now.AddMinutes(5);
// I also tried:
// var expireDate = DateTime.UtcNow.AddMinutes(5);
// and that did not work either.
HttpContext.Current.Cache.Insert(remoteIp, 1, null, expireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
else
// increment the existing value
HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1;
我第一次运行 UpdateCountFor("127.0.0.1") 时,它将 1 插入到缓存中,键为“127.0.0.1”,并且从现在开始的绝对到期时间为 5 分钟,正如预期的那样。然后每次后续运行都会增加缓存中的值。但是,在等待 10 分钟后,它会继续增加 Cache 中的值。该值永不过期,也永远不会从缓存中删除。这是为什么呢?
据我了解,绝对过期时间意味着该项目大约会在那个时候被删除。难道我做错了什么?我是不是误会了什么?
我预计该值会在 5 分钟后从缓存中删除,但它会一直保留在那里,直到我重建项目。
这一切都在我本地机器上的 .NET 4.0 上运行。
【问题讨论】:
你的 web.config 中有什么奇怪的缓存配置设置吗? 不,我有默认的 web.config 【参考方案1】:原来这一行:
HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1;
删除之前的值并重新插入没有绝对或滑动到期时间的值。为了解决这个问题,我必须创建一个辅助类并像这样使用它:
public class IncrementingCacheCounter
public int Count;
public DateTime ExpireDate;
public void UpdateCountFor(string remoteIp)
IncrementingCacheCounter counter = null;
if (HttpContext.Current.Cache[remoteIp] == null)
var expireDate = DateTime.Now.AddMinutes(5);
counter = new IncrementingCacheCounter Count = 1, ExpireDate = expireDate ;
else
counter = (IncrementingCacheCounter)HttpContext.Current.Cache[remoteIp];
counter.Count++;
HttpContext.Current.Cache.Insert(remoteIp, counter, null, counter.ExpireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
这将解决这个问题,让计数器在绝对时间正确过期,同时仍对其进行更新。
【讨论】:
这是API太有用的情况。而不是强迫你使用你看到的索引器的存储机制会导致奇怪 我同意。我最终只是使用ilspy 浏览了源代码以找出所有这些。【参考方案2】:尝试使用 DateTime.UtcNow 而不是 datetime.Now 来计算您的超时时间。您可能会遇到以下问题:
absoluteExpiration 类型: System.DateTime 插入的对象过期并被删除 从缓存中。 为了避免可能 本地时间问题,例如更改 从标准时间到夏令时 时间,使用 UtcNow 而不是 Now 这个参数值。如果你正在使用 绝对到期 滑动过期参数必须是 NoSlidingExpiration。
【讨论】:
将其更改为使用 DateTime.UtcNow.AddMinutes(5);没用:( 无赖我认为你的代码是正确的。在我看来是对的。它什么时候从缓存中删除? .您可以向 cache.insert 添加回调以了解它何时被删除。也许这会给你一些关于触发它的线索。 就是这样,它根本不会从缓存中删除。这就是我遇到的问题。我预计它会在 5 分钟后被删除,但它会一直保留在那里,直到我重建项目。 TimeSpan.FromMinutes(number_of_minutes)【参考方案3】:有一个比 smoak 发布的更简单的答案。使用该示例作为起点,下面的更新代码可以工作并且不需要重新插入。之所以可行,是因为类是引用类型。因此,当您更新类实例中的计数器时,它不会导致缓存触发更新。
public class IncrementingCacheCounter
public int Count;
public void UpdateCountFor(string remoteIp)
IncrementingCacheCounter counter = null;
if (HttpContext.Current.Cache[remoteIp] == null)
counter = new IncrementingCacheCounter Count = 1;
HttpContext.Current.Cache.Insert(remoteIp, counter, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
else
counter = (IncrementingCacheCounter)HttpContext.Current.Cache[remoteIp];
counter.Count++;
【讨论】:
以上是关于ASP.net 缓存绝对过期不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Asp.net 缓存在 IIS 上不起作用。 IIS上有没有设置
自定义授权过滤器在 ASP.NET Core 3 中不起作用