Caching Method Results in ASP.NET 2.0 using Generics & Delegates

Today I found myself coding a fairly familiar pattern - checking whether there was an entry in the ASP.NET cache with a particular key, if not, executing a method and adding the result to the cache, and either way, returning the result.

I wondered whether there was a "nice" way to do this using generics and anonymous delegates. This is what I came up with...

public delegate T MethodExecution<T>();
public static T GetCachedMethod<T>(string key, DateTime absoluteExpiration, MethodExecution<T> method)
{
    if (HttpContext.Current.Cache[key] == null)
        HttpContext.Current.Cache.Insert(key,
            method(),
            null, absoluteExpiration, Cache.NoSlidingExpiration);

    return (T)HttpContext.Current.Cache[key];
   
}

Now, to use this method, I could write the following to return a cached (by one day) result of the method SomeMethodThatReturnsADataSet.

return GetCachedMethod<DataSet>(key, DateTime.Now.AddDays(1),
                delegate() { return SomeMethodThatReturnsADataSet(myParam); });

I'm not sure whether this just makes things more obscure - any comments? :)

Published 14 November 2005 08:42 PM by James Crowley

Comments

# Brian Scott said on 14 November, 2005 05:16 PM
This is great. Exposing this directly through an API may confuse some users. Maybe just expose a method that takes a delegate for the API. I think it is great for an internal implementation.
# Jerry Pisk said on 14 November, 2005 08:09 PM
See my comment to your follow up post, there's a race condition in your code.
# Jeremy Schneider said on 30 November, 2005 12:24 PM
Awesome. I had the exact same question, but then my brain started to hurt so I just Googled it and this is exactly what I was looking for.

Jerry is right though. There is a race condition (if the cache gets invalidated after the if statement executes and before the return statement executes) I have actually had this crash my site a few times!

Leave a Comment

(required) 
(required) 
(optional)
(required)