Cache Revisited

Have you ever created a new email message with the main objective being to send someone an attachment and then forget to attach said attachment?  Apparently I did something similar to that in my last post.  At the time of the post, I couldn't get the attach file method to work so I intended to add it later, but I didn't.  That makes me a sad panda :(

I've been using a variant of this caching method with good results for quite some time.  So to make amends I'm going to post an updated version AND a proper sample solution.  And this time, I will remember to attach it.

 

using System;
using System.Reflection;
using System.Web;
using System.Web.Caching;
using log4net;

namespace BDI.Caching
{
public class CacheHelper
{
private static readonly ILog log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType );

private static readonly bool isInfoEnabled = log.IsInfoEnabled;
private static readonly Cache cache = HttpRuntime.Cache;
private CacheHelper() {}

public static T GetFromCache<T>(
string key,
int cacheTimeInMinutes,
CacheExpiration cacheExpiration,
Func<T> retrieveMethod ) where T : class
{

var target = cache[key] as T;

if ( target == null )
{
if (isInfoEnabled)
log.Info("Cache miss for key:" + key + " type:" + typeof (T));

target = retrieveMethod();

var absoluteExpiration = Cache.NoAbsoluteExpiration;
var slidingExpiration = Cache.NoSlidingExpiration;

switch (cacheExpiration)
{
case CacheExpiration.Sliding:
slidingExpiration = new TimeSpan(0, cacheTimeInMinutes, 0);
break;
case CacheExpiration.Absolute:
absoluteExpiration = DateTime.Now.AddMinutes(cacheTimeInMinutes);
break;
}

cache.Insert(key, target, null, absoluteExpiration,
slidingExpiration, CacheItemPriority.Normal, OnRemove);

}
else
{
if ( isInfoEnabled )
log.Info( "Cache hit for key:" + key + " type:" + typeof( T ) );
}

return target;
}

public static void OnRemove( string key, object cacheItem, CacheItemRemovedReason reason )
{
if( isInfoEnabled )
log.Info( "Object removed from cache: Key-" + key + ": Reason-" + reason );
}

public static void RemoveFromCache( string key )
{
if( isInfoEnabled )
log.Info( "Object manually removed from cache: Key-" + key );

cache.Remove( key );
}
}
}

Posted 03-31-2009 9:38 PM by anortham
Filed under: ,
Attachment: AutoComplete.zip

[Advertisement]

Comments

DotNetShoutout wrote Cache Revisited - Alan Northam - Devlicio.us
on 04-01-2009 5:33 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

meisinger wrote re: Cache Revisited
on 04-01-2009 10:31 AM

is it my imagination or are there some missing angle brackets in your example code?

anortham wrote re: Cache Revisited
on 04-01-2009 10:43 AM

@meisinger Yup, they got lost in the html river.  I've added them back.

Scott Watermasysk wrote re: Cache Revisited
on 04-04-2009 10:07 PM

One item that jumps out at me is this:

var target = cache[key];  

And then using return (T)target;.

You run the risk of finding an object based on the key but throwing an invalid cast exception.

Might want to consider:

var target = cache[key] as T;

Of course this limits you to reference types, but could save you a hard issue to debug later.

-Scott

anortham wrote re: Cache Revisited
on 04-05-2009 2:40 PM

@Scott

If you look at my earlier post it is written just like that which requires T to be a reference type.  In this case I tried to make it as flexible as possible so I left off that constraint.  However you do have a possible exception.  So take your pick, reference types only or a possible cast exception.

Thomas G Mayfield wrote re: Cache Revisited
on 04-07-2009 11:22 AM

AutoComplete.zip.tgz? Covering your bases? :)

I see a section like that big (target != null) if block and can't help but suggesting a rewrite for clarity--one that tells you what each branch does differently, and that uses far fewer lines:

DateTime absoluteExpiration = Cache.NoAbsoluteExpiration;

TimeSpan slidingExpiration = Cache.NoSlidingExpiration;

switch( cacheExpiration )

{

case CacheExpiration.Sliding:

slidingExpiration = new TimeSpan( 0, cacheTimeInMinutes, 0 );

break;

case CacheExpiration.Absolute:

absoluteExpiration = DateTime.Now.AddMinutes(cacheTimeInMinutes);

break;

}

cache.Insert(key, target, null, absoluteExpiration, slidingExpiration, CacheItemPriority.Normal, OnRemove);

anortham wrote re: Cache Revisited
on 04-07-2009 1:02 PM

Thomas:

Not sure where the tgz came from, that's out of my hands :)

That definitely needs refactoring.  I'll update it asap.

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)