Sunday, May 18, 2008

Caching Revisited

In my last posting I outlined how I used AJAX Page Methods during the page unload event to explicitly clear the cache objects I had been using. I was very pleased with this accomplishment, for it achieved an important improvement for the app, but also marked a milestone in my learning curve of building more sophisticated web apps.

I did some more reading today though and came across this detailed article about ASP.Net caching techniques. I really focused in on the "Sliding Expiration" option and decided to give it a try. Up until now I was just using caching in its simplest form: Cache[key] = object;

What I learned from the article is that a more sophisticated way to add and/or update objects in the cache is with this method:

Cache.Insert(key, object, dependency, absoluteExpiration, slidingExpiration);


Looking at all the options available, I decided to proceed strictly with Sliding Expiration removal of cache objects. Since I know I'll be using the Cache for future modules, I decided to implement a reusable method in my BusinessObjects DLL as follows:

public static void AddToCache(string key, object data)
{
HttpContext.Current.Cache.Insert(key, data, null, DateTime.MaxValue, TimeSpan.FromMinutes(5));
}

With the Cache.Insert method the first two parameters are obvious. The third, the dependency, I set to null. A more sophisticated technique would be to use it to automatically delete the cache object when the data source changes. But for now I'll leave this for the future.

The fourth parameter is set to "DateTime.MaxValue" as a default of sorts when Sliding Expiration is what you want to implement. Apparently the 4th parameter is ignored if the last parameter is anything but TimeSpan.Zero but I don't know that for a fact. In other words, if you desired an absolute expiration time instead then you would use this syntax:

HttpContext.Current.Cache.Insert(key, data, null, specifyAbsoluteTimeHere, TimeSpan.Zero);

The fifth & last parameter is set to whatever time (in seconds, minutes, etc.) that you wish the cached object to be cleared if not accessed. If it is accessed within that time then the countdown is reset. Why 5 minutes? It's an arbitrary value that I chose but I think one that is appropriate for the application I'm building.

I should mention that back in my webform code page I use a simple, but effective, approach to ensure that each cached object is always available:

if (Cache[key] == null)
Tools.AddToCache(key, GetDataForThisKey());

DataTable dataTable = (DataTable)Cache[key];

Notes
  1. Everything in italics in the code sample is to be replaced as per your particular situation.
  2. "Tools" is a general-purpose class that resides in my BusinessObjects project.
  3. This code example refers to one where the cached object is a DataTable. This is most often the case for my cached objects but clearly can be whatever type of object you want.
In summary, a little tweaking has provided a general-purpose way to use caching effectively, without worrying about the cached objects building up over time!

No comments:

Post a Comment