Wednesday, September 1, 2004


Using the ASP.NET cache from …. anywhere

Once upon a time….

I needed a smart way to cache data in memory. It should have a fixed expire date but also be smart enough to delete items that were not used in a long time. Frist I implemented a very simple system using a HashTable with a garbage collection thread.

A simplified version:

private static System.Collections.Hashtable _memoryCollection = new System.Collections.Hashtable();

public void setItem(CacheItem cacheItem)

   _memoryCollection[cacheItem.cacheID] = cacheItem;

public CacheItem getItem(string cacheID)

   CacheItem cacheItem = (CacheItem) _memoryCollection[cacheID];

if (null != cacheItem)
// Note; no interlocked. Who cares if we loose a hit or two
return cacheItem;

A garbage collector can be scheduled using::

System.Threading.Thread thread = new Thread(new ThreadStart(garbageCollector));

Which does something like this:

System.DateTime now = System.DateTime.Now;
System.Collections.ArrayList itemsToDelete =
new System.Collections.ArrayList();

foreach (DictionaryEntry item in _memoryCollection)
  CacheItem cacheItem = (CacheItem) item.Value;

  if (cacheItem.expireDate < now || 0 == cacheItem.usageCount)
    itemsToDelete.Add (item.Key);
// Use this if you really care: Interlocked.Exchange(cacheItem.usageCount, 0); 
cacheItem.usageCount = 0;

// Delete the items
foreach (string key in itemsToDelete)


Then I saw the light and used the ASP.NET built in cache. The really cool thing is that it works from anywhere;, a standalone .exe, a .net component registered in com+ (i.e. inherits from EnterpriseServices). And it gives you garbage collection, sliding and fixed expire etc for free

The clue is not to hit the stones together but to add a reference to System.Web.dll and use the System..Web.HttpRuntime.Cache to get a reference to the cache.


private static System.Web.Caching.Cache _memoryCache;

// Somewhere:
_memoryCache = System.Web.HttpRuntime.Cache;

public void setItem(CacheItem cacheItem)

   _memoryCache.Insert(cacheItem.cacheID, cacheItem.cacheValue, null, cacheItem.expireDate, System.Web.Caching.Cache.NoSlidingExpiration, cacheItem.priority, null);

public CacheItem.getItem(string cacheID)

   return  (CacheItem) _memoryCache.Get(cacheID);

YMMV but I hope the code above gives the idea.


No comments:

Post a Comment