18

I've got a simple object being cached like this:

_myCache.Add(someKey, someObj, policy);

Where _myCache is declared as ObjectCache (but injected via DI as MemoryCache.Default), someObj is the object i'm adding, and policy is a CacheItemPolicy.

If i have a CacheItemPolicy like this:

var policy = new CacheItemPolicy 
{ 
   Priority = CacheItemPriority.Default, 
   SlidingExpiration = TimeSpan.FromHours(1)
};

It means it will expire in 1 hour. Cool.

But what will happen is that unlucky first user after the hour will have to wait for the hit.

Is there any way i can hook into an "expired" event/delegate and manually refresh the cache?

I see there is a mention of CacheEntryChangeMonitor but can't find any meaninful doco/examples on how to utilize it in my example.

PS. I know i can use CacheItemPriority.NotRemovable and expire it manually, but i can't do that in my current example because the cached data is a bit too complicated (e.g i would need to "invalidate" in like 10 different places in my code).

Any ideas?

RPM1984
  • 72,246
  • 58
  • 225
  • 350
  • btw, no need to set Priority = CacheItemPriority.Default, since this Default value is set by default :) – Prokurors Apr 04 '15 at 07:42

3 Answers3

16

There's a property on the CacheItemPolicy called RemovedCallback which is of type: CacheEntryRemovedCallback. Not sure why they didn't go the standard event route, but that should do what you need.

http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheitempolicy.removedcallback.aspx

BFree
  • 102,548
  • 21
  • 159
  • 201
  • 4
    Well, the link doesn't contain a code sample - in fact MSDN is very short on code samples for the runtime caching. I eventually figured it out, but you could have saved me an hour by providing an example. – NightOwl888 Mar 16 '13 at 15:59
  • 3
    [CodeProject sample](http://www.codeproject.com/Articles/290935/Using-MemoryCache-in-Net-4-0) "Using MemoryCache in .NET 4.0" – richaux Nov 21 '13 at 16:56
5

Late to the party with this one but I've just noticed an interesting difference between CacheItemUpdate and CacheItemRemove callbacks.

http://msdn.microsoft.com/en-us/library/system.web.caching.cacheitemupdatereason.aspx

In particular this comment:

Unlike the CacheItemRemovedReason enumeration, this enumeration does not include the Removed or Underused values. Updateable cache items are not removable and can thus never be automatically removed by ASP.NET even if there is a need to free memory.

Dorian Farrimond
  • 413
  • 5
  • 13
2

This is my way to use CacheRemovedCallback event when cache expired.

I share for whom concern.

public static void SetObjectToCache<T>(string cacheItemName, T obj, long expireTime)
        {
            ObjectCache cache = MemoryCache.Default;

            var cachedObject = (T)cache[cacheItemName];

            if (cachedObject != null)
            {
                // remove it
                cache.Remove(cacheItemName);
            }

            CacheItemPolicy policy = new CacheItemPolicy()
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds(expireTime),
                RemovedCallback = new CacheEntryRemovedCallback(CacheRemovedCallback)
            };

            cachedObject = obj;
            cache.Set(cacheItemName, cachedObject, policy);
        }

public static void CacheRemovedCallback(CacheEntryRemovedArguments arguments)
            {
                var configServerIpAddress = Thread.CurrentPrincipal.ConfigurationServerIpAddress();
                long configId = Thread.CurrentPrincipal.ConfigurationId();
                int userId = Thread.CurrentPrincipal.UserId();
                var tagInfoService = new TagInfoService();
                string returnCode = string.Empty;

                if (arguments.CacheItem.Key.Contains("DatatableTags_"))
                {
                    // do what's needed
                    Task.Run(() =>
                    {
                    });
                }

            }
Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62