Search code examples
c#asp.net.netcachinghttpcontext

Using SQL query / file paths as cache keys in ASP.NET HttpContext caching


I'm toying with the idea of using file paths and potentially raw sql as cache keys in my asp.net HttpContext cache. These items will be cached for minutes only.

My question is whether or not I will run into incorrectly cached data and how often. Everything seems peachy in a single user test environment, but what would happen with multiple users under load?

My intuition tells me this is a bad idea, but when trying to confirm it is a bad idea, I've found some conflicting information that makes me think it could be ok.

For instance, there is no length restrictions on cache keys since cache keys are hashed and the Dictionary has internal collision resolution. Does this mean I'm ok? The results of incorrectly cached data would be really catastrophic for the application.


Solution

  • The answer is (sort of) in your question. The cache keys are hashed. The longer the cache keys are, the more likely there will be collisions. It is therefore better to have shorter cache keys.

    The approach I normally take is to make the key as concise (but still determinate and unique) as possible. This usually means starting with an object type name followed by the key that identifies the object with a standardized delimiter in between. This solution scales easily because you can just tack on additional information if you need to differentiate your cache in some other way.

    // this will be used to cache the instance MyClass with 
    // ID (key) value of MyClassKey (usually this is a Guid or int)
    var key = "MyClass|MyClassKey";
    
    // this will be used to cache the result of the call to 
    // MyClass.MyFunctionName(Parameter1Value, Parameter2Value);
    var key = "MyClass|MyFunctionName|Parameter1Value|Parameter2Value";
    

    On a side note, if you are using .NET framework 4 or higher System.Runtime.Caching is a more robust and pluggable framework than System.Web.Caching, and it works very similarly, but doesn't depend on System.Web.