ASP.net Cache Absolute Expiration not working

后端 未结 3 1548
渐次进展
渐次进展 2021-02-07 11:17

I am storing a single integer value in HttpContext.Cache with an absolute expiration time of 5 minutes from now. However, after waiting 6 minutes (or longer), the integer value

相关标签:
3条回答
  • 2021-02-07 11:45

    It turns out that this line:

    HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1;
    

    removes the previous value and re-inserts the value with NO absolute or sliding expiration time. In order to get around this I had to create a helper class and use it like so:

    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);
    }
    

    This will get around the issue and let the counter properly expire at the absolute time while still enabling updates to it.

    0 讨论(0)
  • 2021-02-07 11:51

    There's a simpler answer than what smoak posted. Using that example as a starting point, the updated code below works and doesn't require a re-insert. The reason this works is because classes are reference types. Thus, when you update the counter inside the class instance it doesn't cause the cache to trigger an update.

    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++;
        }
    }
    
    0 讨论(0)
  • 2021-02-07 12:08

    Try using DateTime.UtcNow to calculate your timeout period instead of datetime.Now . You may be running into the issue described below:

    absoluteExpiration Type: System.DateTime The time at which the inserted object expires and is removed from the cache. To avoid possible issues with local time such as changes from standard time to daylight saving time, use UtcNow rather than Now for this parameter value. If you are using absolute expiration, the slidingExpiration parameter must be NoSlidingExpiration.

    0 讨论(0)
提交回复
热议问题