27

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);
    }
}
Community
  • 1
  • 1
John Ruiz
  • 2,371
  • 3
  • 20
  • 29

1 Answers1

18

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. :)

Haney
  • 32,775
  • 8
  • 59
  • 68
  • 1
    However, if I create a cache policy (using the code above) /each time/ I add an item, it should then work as expected, right? – John Ruiz Jun 06 '13 at 21:48
  • Yes, precisely! Or if you're a little more flexible, keep your shared instance of the CacheItemPolicy and use the SlidingExpiration of N seconds. – Haney Jun 06 '13 at 21:49
  • 1
    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. – John Ruiz Jun 06 '13 at 21:51
  • 2
    One thing that might make you feel better is that the CacheItemPolicy is a struct, so it's very cheap to create per call. – Haney Jun 06 '13 at 21:52
  • @DavidHaney what do you mean with "near future"? Can this explain the behavour I am seeing here: http://stackoverflow.com/questions/23461749/self-renewing-memorycache ? – Jesper Lund Stocholm May 05 '14 at 06:56