The typical procedure to work with cache is
1.to check if item for specified key exist in a cache;
2.if yes, return it;
3.if no, create it (e.g load from database),
4.save to the cache
5. and then return it.
Some developers use the code like the following:
If (DataCache.GetCache["key"] == null)
{ // code for loading object
...
DataCache.SetCache("key", obj);
}
return DataCache.GetCache["key"]; //Not good, can cause problems (at least in ASP.Net 2.0).
Sometimes SetCache is not effected immediately(or expired immediately) and subsequent GetCache returns null.
Back in 2006 I lost a lot of time trying to debug the problem in DotNetNuke "DataCache.GetCache usage pattern causes random Null reference exceptions".
Now in a different application I noticed the same unreliable pattern.
To avoid mistakes and make process of getting objects from cache consistent, I've created a Generic function with delegate as a parameter to implement the safe pattern.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
public static class CacheHelper
{
public delegate object CreateInstanceDelegate(); //TODO how to declare delegate that returns generic type?
public static T LoadFromCache<T>(String cacheKey, CreateInstanceDelegate dlgt) where T:class
{
T coll = HttpRuntime.Cache[cacheKey] as T;
if (coll == null)
{
coll = dlgt() as T;
HttpRuntime.Cache[cacheKey] = coll;
}
return coll;
}
}
MyClass entity =
CacheHelper.LoadFromCache<MyClass >(sCacheKey, delegate
{
return LoadFromDb(localParameters);
});
posted @ Thursday, October 04, 2007 9:13 PM