Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Cold, Hard, Cache!

Don't get me wrong, I really like the Asp.Net Cache (or HttpRuntime.Cache or Uncle Daddy if you want to call it that... you're a little odd aren't you?), but sometimes it just can't be trusted.  I mean, I just gave you (the cache) my precious object a second ago and now you claim you don't have it?  Did you lose it?  Did you sell it on eBay?  Did you pawn it to support your habit?  Please at least tell me you got a decent price for it. 

One of the great things about the cache is also what makes it so untrustworthy.   Objects stored there are referenced with WeakReference so if your sever starts getting low on memory GC will collect objects from the cache to free some up.  Also take into account that if you put an object in Cache and set it to expire after X minutes, when you go back to retreive it, do you really know how long it's been?

So what we want is a way to tell the cache "I want this specific object (a yellow Tonka dumptruck, metal, not plastic) and if you don't have it, here are instructions on how to get it".

Something like this:

using System; using System.Reflection; using System.Web; using System.Web.Caching; using log4net; public delegate bool Factory<T>( out T instance ); public class CacheHelper { private static readonly ILog log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType ); private static readonly Cache cache = HttpRuntime.Cache; private CacheHelper(){} public static T GetFromCache<T>(string key, int cacheTimeInMinutes, Factory<T> retrieveMethod) where T:class { T target = cache[key] as T; if(target == null) { log.Info( "Cache miss for key:" + key + " type:" + typeof(T)); if(retrieveMethod(out target)) { cache.Insert( key, target, null, DateTime.Now.AddMinutes( cacheTimeInMinutes ), Cache.NoSlidingExpiration, CacheItemPriority.Normal, OnRemove ); } } else { log.Info( "Cache hit for key:" + key + " type:" + typeof(T)); } return target; } public static void OnRemove( string key, object cacheItem, CacheItemRemovedReason reason ) { log.Info( "Object removed from cache: Key-" + key + ": Reason-" + reason); } public static void RemoveFromCache(string key) { cache.Remove( key ); } }

Usage would look like this:

List<string> searchList = CacheHelper.GetFromCache<List<string>>( key, 5, delegate( out List<string> instance ) { return SomeClass.GetSearchList( key, out instance ); } );

I call it the code equivalent of "Trust but verify".


Posted 03-06-2008 10:04 PM by anortham

[Advertisement]

Comments

DotNetKicks.com wrote Cold, Hard, Cache!
on 03-07-2008 8:06 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Will Sullivan wrote re: Cold, Hard, Cache!
on 03-07-2008 11:20 AM

Heheh.  I beat you to it.  I've used this pattern for a long time.

statestreetgang.net/post.aspx

Its a great little pattern.  You can also apply it to the session state, view state, or any other "bag" type storage.  One of my fav uses is for session state-scoped singletons...

anortham wrote re: Cold, Hard, Cache!
on 03-07-2008 3:25 PM

Will,

If I'd known we were in a race, I'd have kneecapped you with a pipe :)

Sam wrote re: Cold, Hard, Cache!
on 03-07-2008 8:57 PM

I like your sense of humor. It's funnier than your code, but less useful.

Cold, Hard, Cache! - Alan Northam « Noocyte’s Weblog wrote Cold, Hard, Cache! - Alan Northam &laquo; Noocyte&#8217;s Weblog
on 03-11-2008 1:45 PM

Pingback from  Cold, Hard, Cache! - Alan Northam &laquo; Noocyte&#8217;s Weblog

Alan Northam wrote Practical Implementation - spending some cache.
on 03-17-2008 10:54 PM

Take a look at my previous post for the details on a cache helper method that I like to use. In this

Luka wrote re: Cold, Hard, Cache!
on 05-23-2008 3:06 PM

Hi Alan,

I'm trying to store data table into cache, without much success.

I have a static method that suppose to return datatable in case that it is not already in cache (retrieve method). I admit, I don't know much with anonymous methods, but wander if this pattern should work for datatable types?

Community Blogs wrote Cache Access Pattern Revised
on 07-07-2008 9:52 AM

Karl Seguin has an interesting post about using System.Func to fight repetitive code blocks , which actually

Readed By Wrocław NUG members wrote Cache Access Pattern Revised
on 07-07-2008 5:25 PM

Karl Seguin has an interesting post about using System.Func to fight repetitive code blocks , which actually

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)