HttpRuntime.Cache vs. HttpContext.Current.Cache

Here's a development tip I came across on one of the ASP.NET discussion lists I'm on, at AspAdvice.com.

Original question:
Is there a difference in accessing the Cache of an application when calling HttpRuntime.Cache vs. HttpContext.Current.Cache?  I "think" I remember reading about a difference in the two a few years ago, but I don't remember the specifics.  This assumes that I am within a web application.

Answer from Rob Howard:
HttpRuntime.Cache is the recommended technique.

Calling the HttpContext does some additional look-ups as it has to resolve the current context relative to the running thread.

I use HttpContext.Current in a lot of the code I write too; but touching it as little as possible. Rather than calling HttpContext.Current repeatedly it's best to hang onto a reference and pass it around (when possible).

If you're in a component HttpRuntime.Cache is still the recommendation.

That said... the differences in performance are not going to be noticeable in 99% of the applications many of us write. The cases where it is going to matter is the 1% (or less) where you're trying to squeeze every last drop of performance out of you system. But this is a *minor* performance tweak, e.g. eliminating a database call, web service call or other out-of-process call in the application is definitely a better place to spend optimizing code.

For example, if you have 5 database calls in a particular code path reducing (or even optimizing) the queries is a much better use of time.

So yes, HttpRuntime.Cache is recommended but likely won't make a difference in most applications.

Another reply from James Shaw at CoverYourASP.NET:
I discovered another *great* reason to use HttpRuntime too, when writing my unit tests - HttpRuntime.Cache is always available, even in console apps like nunit!

http://www.coveryourasp.net/UnittestingandCaching

I never use HttpContext anymore, even in class libraries.

20 Comments

  • The Cache member of System.Web.UI.Page refers to HttpContext.Cache anyway, so I don't really think it's necessary to completely get rid of references to HttpContext.

  • Karl and Matt,



    As Rob says, HttpRuntime.Cache is more efficient because HttpContext.Current requires additional lookups, as you can see in a disassembler starting from HttpContext.Current. That was the point of this post.



    I'm not comparing HttpRuntime.Cache to HttpContext.Cache (since the latter is a pass-through to the former, as Karl pointed out), nor am I comparing anything to Page.Cache (though this ISN'T a simple pass-through), nor am I advocating getting rid of all references to HttpContext.



    --Peter

  • Thank you. I just spent a fair number of hours trying to understand why I had one method failing everytime I would attempt to load a dataset from the Cache object into a local object to use to perform processing. I had been using Context.current.cache route as well as httpcontext.current.cache and continuously got error after error. Only when I changed it to httpruntime.cache did I finally start getting my dataset back out of the cache, using it and reloading the changes into the Cache object again.

    What drove me the most insane with this is that I have used the following ( and similiar to the following ) countless times before.

    ' From an External Class File
    Imports System.Web.HttpContext

    Dim userDS As New DataTable
    userDS = HttpContext.Current.Cache.Item("Cache").tables("tUser") ' load the cache into a localDS

    Yet, only on this new application did I finally get some form of error.


    One question I have then is, why does the HTTPContext.Current.Cache call work sometimes, while other times I need to use HTTPRuntime.Cache?

  • Sage,

    I'm guessing the problem is that HttpContext.Current is null sometimes, so you're getting a NullReferenceException. One cause for this is if you're calling the code from outside a web page request--so, if you have the same code called from a web request and called from somewhere else, it'll fail in the latter case.

    As I said, since HttpRuntime.Cache always works and is a more direct way to get at the cache, just use that instead of going through HttpContext.

    --Peter

  • Just to clarify...

    The HttpRuntime.Cache is available to all "users" (IP's, IIS Session, etc.) on the 'net but HttpContext is only available to the current IIS session?

  • Thanks for this post.

    I was having the problem that others were having with HttpContext.Current being null when outside of a request. This post showed me the light.

  • I found another wierd issue, I write the return value of HttpRuntime.GetHashcode() into log file, sometimes I can see different hascode value in log file.That is to see there are two different instance of Cache at the same time. and I also get different value from cache use the same key.

  • Hi i am wrking on caching on website and i realized the fact that HttpContext.Current.Cache does not work for console app. So if you need to use caching everywhere then prefer its static approach HttpRuntime.Cache.

  • Hi i used HttpRuntime.Cache for lookups in our web application which runs on server .I created a page in which i'm calling load cache method and this page can be accessed by admin.
    As admin a loaded the cache(fot 20 hrs), logoff and i signed in as a different user,tried to view the cached data but the cache is becoming null and again it is loading it.
    Can any one help me out?

  • Learn a lot from this article and comments. What I prefer will be HttpRuntime.Cache, because it will work in my test project (unit test).

  • Thank you indeed, solved quite a big problem and explained it very clearly :)

    I feel much better now :)

  • Thanks for article. I was very useful. Rescued me from a small headache :) By the way, Is there anyway to use HttpContext.Current within WCF service? I don't need this at this time. Just wondering If It can be done with playing with bindings.

  • Had the common problem of HttpContext.Current being null. These comments explained why. That's folks!

    Reason: The call was being made outside of a page request. As in the case in AJAX and OnRemovedItem

    Solution: Use HttpRuntime.Cache for caching

  • I've been using HttpContext.Cache in an application with an absolute expiration of 1 day on several cached objects, however I have since learned that my assumption that HttpContext persists between sessions was incorrect. Apparently HttpContext is per session based and HttpRuntime is application based. Thanks for the article.

  • Thank you for posting this!

  • Thank you very much.. This is very helpfull for all developers.

  • HttpContext.Current.Cache cannot be access threw delegation event like CacheItemRemovedCallback

    However HttpRuntime.Cache can.... since no current context needs to be resolved.

  • Hello, thanks for all the information.

    I'm wondering about, is it safe/reliable to use HttpRuntime.Cache object in Console applications such as windows services, specially who serves WCF services in it?

    Do you know any experience about that?

    Note: i've already tried and it seems, it is works even with the expire callback function. But i'm not sure it is the best practice.

    Note2: as i see, in .Net 4, microsoft published an abstract base class for caching in non-web applications. But currently i'm using 3.5

  • Thanks for the post. very informative.

  • We have implemented API for both web application and console. In this API, we put code snippet to include HttpContext.Current.Cache.
    Getting NullReferenceException.

    Can any one help me out to?

Comments have been disabled for this content.