Locking HttpRuntime.Cache for lazy loading

2019-05-10 11:36发布

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条回答
Evening l夕情丶
2楼-- · 2019-05-10 12:21

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.

查看更多
相关推荐>>
3楼-- · 2019-05-10 12:22

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.

查看更多
Deceive 欺骗
4楼-- · 2019-05-10 12:32

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

查看更多
干净又极端
5楼-- · 2019-05-10 12:42

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.

查看更多
登录 后发表回答