Expiring a cached item via CacheItemPolicy in .NET MemoryCache

21,623

Caching adheres to UTC time to offer uniform time calculations, so you specify a point in time at which the cached entry should expire, in UTC, and the cache will calculate the appropriate difference from now and expire it as expected.

Your code will not work as expected since your absolute expiration will be before your cache item is entered once cacheExpiryInSeconds seconds pass, resulting in immediate eviction. You cannot share a CacheItemPolicy instance when AbsoluteExpiration is set in the near future, annoying I know. :)

Share:
21,623

Related videos on Youtube

John Ruiz
Author by

John Ruiz

Security Operations at GitHub

Updated on January 05, 2020

Comments

  • John Ruiz
    John Ruiz over 4 years

    I'm confused about the AbsoluteExpiration property on CacheItemPolicy.

    The MSDN documentation for it says "The period of time that must pass before a cache entry is evicted." It uses a System.DateTimeOffset to define the "period of time".

    But if you look at DateTimeOffset's MSDN documentation, it says that it "represents a point in time ... relative to Coordinated Universal Time (UTC)." Reference also this StackOverflow thread.

    Do you see the problem? AbsoluteExpiration expects a "period in time" (like 5 seconds or 2 hours), but it requires an object that represents a "point in time" (like Dec 21, 2012, 06:14:00 EST).

    In the code below, I define a single policy for all items. I want every item to expire cacheExpiryInSeconds seconds after they are added. Can someone verify that I'm doing this the correct way?

    public class MyCache : IRoutingInfoCache
    {
        MemoryCache _routingInfoCache;
        CacheItemPolicy _cachePolicy;
    
    
        public MyCache(int cacheExpiryInSeconds)
        {
            _routingInfoCache = new MemoryCache("myCache");
            _cachePolicy = new CacheItemPolicy() {
                AbsoluteExpiration = 
                    new DateTimeOffset(
                        DateTime.UtcNow.AddSeconds(cacheExpiryInSeconds))
            };
        }
    
    
        public void Put(string key, object cacheItem)
        {
            // based on how I constructed _cachePolicy, will this item expire
            // in cacheExpiryInSeconds seconds?
            _routingInfoCache.Add(new CacheItem(key, cacheItem), _cachePolicy);
        }
    }
    
  • John Ruiz
    John Ruiz almost 11 years
    However, if I create a cache policy (using the code above) /each time/ I add an item, it should then work as expected, right?
  • Haney
    Haney almost 11 years
    Yes, precisely! Or if you're a little more flexible, keep your shared instance of the CacheItemPolicy and use the SlidingExpiration of N seconds.
  • John Ruiz
    John Ruiz almost 11 years
    I explicitly don't want to "reset the clock" each time an item is accessed, so I think that AbsoluteExpiration is for me. Thanks for mentioning it, though.
  • Haney
    Haney almost 11 years
    One thing that might make you feel better is that the CacheItemPolicy is a struct, so it's very cheap to create per call.
  • Jesper Lund Stocholm
    Jesper Lund Stocholm about 10 years
    @DavidHaney what do you mean with "near future"? Can this explain the behavour I am seeing here: stackoverflow.com/questions/23461749/self-renewing-memorycac‌​he ?