<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Alan Northam : ASP.NET, C#</title><link>http://devlicio.us/blogs/alan_northam/archive/tags/ASP.NET/C_2300_/default.aspx</link><description>Tags: ASP.NET, C#</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Cold, Hard, Cache!</title><link>http://devlicio.us/blogs/alan_northam/archive/2008/03/06/cold-hard-cache.aspx</link><pubDate>Fri, 07 Mar 2008 04:04:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:39576</guid><dc:creator>anortham</dc:creator><slash:comments>9</slash:comments><description>&lt;p&gt;Don&amp;#39;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&amp;#39;re a little odd aren&amp;#39;t you?), but sometimes it just can&amp;#39;t be trusted.&amp;nbsp; I mean, I just gave you (the cache) my precious object a second ago and now you claim you don&amp;#39;t have it?&amp;nbsp; Did you lose it?&amp;nbsp; Did you sell it on eBay?&amp;nbsp; Did you pawn it to support your habit?&amp;nbsp; Please at least tell me you got a decent price for it.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;One of the great things about the cache is also what makes it so untrustworthy. &amp;nbsp; Objects stored there are referenced with &lt;a href="http://msdn2.microsoft.com/en-us/library/system.weakreference.aspx" target="_blank"&gt;WeakReference&lt;/a&gt; so if your sever starts getting low on memory GC will collect objects from the cache to free some up.&amp;nbsp; 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&amp;#39;s been?&lt;/p&gt;
&lt;p&gt;So what we want is a way to tell the cache &amp;quot;I want this specific object (a yellow Tonka dumptruck, metal, not plastic) and if you don&amp;#39;t have it, here are instructions on how to get it&amp;quot;.&lt;/p&gt;
&lt;p&gt;Something like this:&lt;/p&gt;
&lt;p&gt;

using System;
using System.Reflection;
using System.Web;
using System.Web.Caching;
using log4net;
public delegate bool Factory&amp;lt;T&amp;gt;( 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&amp;lt;T&amp;gt;(string key, int cacheTimeInMinutes, Factory&amp;lt;T&amp;gt; retrieveMethod) where T:class
    {
        T target = cache[key] as T;
        if(target == null)
        {
            log.Info( &amp;quot;Cache miss for key:&amp;quot; + key + &amp;quot;  type:&amp;quot; + typeof(T));
            if(retrieveMethod(out target))
            {
                cache.Insert( key, target, null, DateTime.Now.AddMinutes( cacheTimeInMinutes ),
                    Cache.NoSlidingExpiration, CacheItemPriority.Normal, OnRemove );
            }            
        }
        else
        {
            log.Info( &amp;quot;Cache hit for key:&amp;quot; + key + &amp;quot;  type:&amp;quot; + typeof(T));
        }
        return target;
    }

    public static void OnRemove( string key, object cacheItem, CacheItemRemovedReason reason )
    {
        log.Info( &amp;quot;Object removed from cache: Key-&amp;quot; + key + &amp;quot;: Reason-&amp;quot; + reason);
    }

    public static void RemoveFromCache(string key)
    {
        cache.Remove( key );
    }
}&lt;/p&gt;
&lt;p&gt;
Usage would look like this:
&lt;/p&gt;
&lt;p&gt;
List&amp;lt;string&amp;gt; searchList = CacheHelper.GetFromCache&amp;lt;List&amp;lt;string&amp;gt;&amp;gt;(
            key,
            5,
            delegate( out List&amp;lt;string&amp;gt; instance ) { return SomeClass.GetSearchList( key, out instance ); } );
&lt;/p&gt;
&lt;p&gt;
I call it the code equivalent of &amp;quot;Trust but verify&amp;quot;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=39576" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Cache/default.aspx">Cache</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/HttpRuntime.Cache/default.aspx">HttpRuntime.Cache</category></item></channel></rss>