My friend Steve Smith who wrote this article has solved a major problem for me. With his permission I'm duplicating some of his code here.
About one in 50,000 page views, I was getting an "Object Not Set" exception being thrown in kbAlertz.com. This was a mystery for a very long time, and it's finally solved (Thanks Steve :). Here is ( IMHO ) how the typical developer retreives something from the cache in an ASP.NET application.
1: HttpContext ctx = HttpContext.Current;
2: if(ctx.Cache["myCacheDataSet"] != null)
3: {
4: DataSet ds = (DataSet)ctx.Cache["myCacheDataSet"];
5: return ds;
6: }
7: else
8: {
9:
10: DataSet ds = new DataSet;
11:
12: ctx.Cache.Insert("myCacheDataSet",ds,null,DateTime.Now.AddHours(1), TimeSpan.Zero);
13: return ds;
14: }
Steve Smith suggests that you should actually create your object, from the cache, and then check your object != null. This means that you only hit the cache object once, vs. the above method of checking the if the cache item is there, and if so, then hit the cache again, and get your object. Once in a blue moon, the object acually falls from cache in the time between (Is it there = true) and (ok it's there, give it to me), thereby creating a null reference exception.
1:
2: Object cacheItem = Cache[key] as DataTable;
3: if(cacheItem == null)
4: {
5: cacheItem = GetData();
6: Cache.Insert(key, cacheItem, null, DateTime.Now.AddHours(1), TimeSpan.Zero);
7: }
8: return (DataTable)cacheItem;
So I built a couple of static helper methods that will let me easily get object from the cache.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11: public static object RetrieveObjectFromCache(string CacheName, HttpContext ctx)
12: {
13: object cacheItem = ctx.Cache[CacheName.ToLower()];
14: return cacheItem;
15: }
16: public static object RetrieveObjectFromCache(string CacheName)
17: {
18: object cacheItem = Global.RetreiveObjectFromCache(CacheName, HttpContext.Current);
19: return cacheItem;
20: }
21:
And Finally, I would use these static methods through out my code like the following ...
1: DataSet dsTmp = (DataSet)Global.RetrieveObjectFromCache("myCachedDataSet");
2: if(dsTmp != null)
3: {
4:
5: }
6: else
7: {
8:
9: }