Locking HttpRuntime.Cache for lazy loading
Asked Answered
H

4

3

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.

Hildebrand answered 15/1, 2009 at 17:35 Comment(0)
V
10

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

Vowelize answered 15/1, 2009 at 17:40 Comment(0)
O
5

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.

Oblivion answered 15/1, 2009 at 17:45 Comment(1)
Just because the Cache object won't smash-up under multithreaded access, doesn't mean that the non-atomic 'check if something's cached, add it if it's not" sequence doesn't need some kind of protection.Duisburg
D
1

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.

Deposition answered 11/7, 2009 at 17:25 Comment(0)
H
0

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.

Horus answered 23/5, 2015 at 8:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.