Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine Sliding and Absolute Expiration

Tags:

I want to use System.Runtime.Caching.MemoryCache for caching some of my objects. I want to be sure that the object is refreshed once a day (absolute expiration) but I also want to make it expire if it hasn't been used in the last hour (sliding expiration). I try to do:

object item = "someitem";
var cache = MemoryCache.Default;
var policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now.AddDays(1);
policy.SlidingExpiration = TimeSpan.FromHours(1);
cache.Add("somekey", item, policy);

But I'm getting a "ArgumentException" with "AbsoluteExpiration must be DateTimeOffset.MaxValue or SlidingExpiration must be TimeSpan.Zero."

like image 749
Andres Avatar asked May 13 '13 14:05

Andres


1 Answers

You can implement both schemes cache expiration by using CacheEntryChangeMonitor. Insert a cache item without information with absolute expiration, then create a empty monitorChange with this item and link it with a second cache item, where you will actually save a slidingTimeOut information.

        object data = new object();
        string key = "UniqueIDOfDataObject";
        //Insert empty cache item with absolute timeout
        string[] absKey = { "Absolute" + key };
        MemoryCache.Default.Add("Absolute" + key, new object(), DateTimeOffset.Now.AddMinutes(10));

        //Create a CacheEntryChangeMonitor link to absolute timeout cache item
        CacheEntryChangeMonitor monitor = MemoryCache.Default.CreateCacheEntryChangeMonitor(absKey);

        //Insert data cache item with sliding timeout using changeMonitors
        CacheItemPolicy itemPolicy = new CacheItemPolicy();
        itemPolicy.ChangeMonitors.Add(monitor);
        itemPolicy.SlidingExpiration = new TimeSpan(0, 60, 0);
        MemoryCache.Default.Add(key, data, itemPolicy, null);
like image 145
dieguitofernandez Avatar answered Sep 17 '22 18:09

dieguitofernandez