Locking HttpRuntime.Cache for lazy loading

4.9k Views Asked by At

We have a website running .NET 2.0 and have started using the ASP.Net HttpRuntime.Cache to store the results of frequent data lookups to cut down our database access.

Snippet:

 
lock (locker)
{
    if (HttpRuntime.Cache[cacheKey] == null)
    {
        HttpRuntime.Cache.Insert(cacheKey, GetSomeDataToCache(), null, DateTime.Today.AddDays(1), Cache.NoSlidingExpiration);       
    }
    return ((SomeData)HttpRuntime.Cache[cacheKey]).Copy();
}

We are pessimistically locking whenever we want to look at the cache. However, I've seen various blogs posted around the web suggesting you lock after you check the cache value instead, to not incur the overhead of the lock. That doesn't seem right as another thread may have written to the cache after the check.

So finally my question is what is the "right" way to do this? Are we even using the right thread synchronization object? I am aware of ReaderWriterLockSlim() but we're running .NET 2.0.

4

There are 4 best solutions below

0
On BEST ANSWER

As far as I know the Cache object is thread safe so you wouldn't need the lock.

0
On

Thread safe. Does it mean all other processes are waiting for ever for your code to finish?

Thread safe is you can be sure that the item you fetch will not be "cut in half" or partially demolished by an update to the cache at the same time you are reading the item.

item = cache.Get(key);

But anything you do after that - another thread can operate on the cache (or any other shared resource). If you want to do something to the cache based on your fetched item being null or not I would not be 100% sure it is not already fixed by a an other instance of your own code being a few CPU instructions ahead servicing another reader of the same page of your on line motor magazine.

You need some bad luck. The risk of other processes bothering about the same cache object, non atomic, in a few lines of code appart, is randomly small. But if it happens you will have a hard time figuring out why the image of the Chevy is sometimes the small suitcase from page two.

1
On

The Cache object in .NET is thread safe, so locking is not necessary. Reference: http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx.

0
On

Your code is probably making you think you'll have that item cached for 1 day and your last line will always give that data to you, but that's not the case. As others said, the cache operations are synchronized so you shouldn't lock at that point.

Take a look here for the proper way of doing it.