Search code examples
c#cachingmemorycache

If I update memory cache using the Set method, with an absolute expiry, will this mean the expiry is extended?


I'm using MemoryCache to store a data table, which contains about 60 rows. Sometimes I want to 'refresh' only part of the table. So I get a the collections of rows I want to refresh based of an id like this:

var cachedDataSet = this.cache.Get(CacheKey) as DataSet;

var dataRows = cachedDataSet.Tables["MyTable"]
                            .AsEnumerable()
                            .Where(x => x.Field<int>("Id") == MyId)
                            .ToList<DataRow>();

I then do some checks against this and based off the results of this will choose to get the data from the DB, remove the current rows from the cachedDataSet and add the new data. I try to do it like this:

var refreshedData = GetMyData(Id);
foreach (var row in dataRows)
{
    cachedDataSet.Tables["MyTable"].Rows.Remove(row);
}

foreach (var row in refreshedData.Tables["MyTable"].Rows)
{
    cachedDataSet.Tables["MyTable"].Rows.Add(row.ItemArray);
}

Finally, I add the cachedDataSet back into the cache using the Set method:

var policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTimeOffset.Now.AddHours(12);
this.cache.Set(CacheKey, cachedDataSet, policy);

So, my main question is that if I extract the cache out into a dataset, amend it and then use the Set method using a new CacheItemPolicy, will this effectively reset the absolute expiration? My understanding is that by using the set method this will overwrite the existing cached item with the new if it exists and insert it if it doesn't. So, my guess is that it will overwrite the cache policy. If so, is there a way of not overwriting the absolute expiration whilst overwriting the values?


Solution

  • Yes it will update expiration time. What you can do is store expiration time together with item itself, in cache. So

    class CachedDataSet {
        public DateTime ExpiresAt {get;set;}
        public DataSet DataSet {get;set;}
    }
    

    Then when refreshing, you first get this item from cache and use it's ExpiresAt as new AbsoluteExpiration value.