ASP.net缓存绝对过期不起作用
我在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分钟后,它会继续增加缓存中的值。 该值永不过期,永远不会从缓存中删除。 这是为什么?
我的理解是,绝对到期时间意味着该项目将在当时大约被移除。 难道我做错了什么? 我误解了什么吗?
我期待5分钟后将值从缓存中删除,但是直到我重建项目时它才停留在那里。
这些都在本地机器上运行在.NET 4.0上。
事实证明,这条线:
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);
}
这将解决这个问题,让计数器在绝对时间正确过期,同时仍然允许更新。
尝试使用DateTime.UtcNow来计算您的超时期限而不是datetime.Now。 您可能会遇到下述问题:
absoluteExpiration类型:System.DateTime插入对象到期并从缓存中删除的时间。 为避免本地时间可能出现的问题,例如从标准时间到夏令时间的更改,请使用UtcNow而不是Now作为此参数值。 如果使用绝对过期,slidingExpiration参数必须为NoSlidingExpiration。
有一个比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++;
}
}
链接地址: http://www.djcxy.com/p/62991.html