锁定HttpRuntime.Cache以进行延迟加载

时间:2009-01-15 17:35:06

标签: multithreading caching synchronization locking httpruntime

我们有一个运行.NET 2.0的网站,并且已经开始使用ASP.Net HttpRuntime.Cache来存储频繁数据查找的结果,以减少我们的数据库访问。

段:

 
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();
}

每当我们想要查看缓存时,我们都会悲观地锁定。但是,我已经看到网上发布的各种博客建议您在检查缓存值后锁定,以免产生锁定开销。这似乎不正确,因为另一个线程可能在检查后写入缓存。

所以最后我的问题是这样做的“正确”方法是什么?我们甚至使用正确的线程同步对象吗?我知道ReaderWriterLockSlim()但我们正在运行.NET 2.0。

4 个答案:

答案 0 :(得分:9)

据我所知,Cache对象是线程安全的,所以你不需要锁。

答案 1 :(得分:5)

.NET中的Cache对象是线程安全的,因此不需要锁定。参考:http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx

答案 2 :(得分:1)

您的代码可能会让您认为您将该项缓存1天,而您的最后一行始终会将该数据提供给您,但事实并非如此。正如其他人所说,缓存操作是同步的,所以你不应该在那时锁定。

在这里查看the proper way of doing it

答案 3 :(得分:0)

线程安全。是否意味着所有其他进程都在等待代码完成?

线程安全,您可以确保在您阅读项目的同时,通过更新缓存,您获取的项目不会被“减半”或部分拆除。

item = cache.Get(key);

但是之后你做的任何事情 - 另一个线程可以在缓存(或任何其他共享资源)上运行。如果你想根据你所获取的项目是否为空而对缓存执行某些操作,我不会100%确定它自己的代码的另一个实例还没有修复它是一些CPU指令前面为另一个读者提供服务你的在线电机杂志的同一页。

你需要运气不好。在几行代码appart中,其他进程对同一缓存对象(非原子)的困扰随机变小。但如果它发生了,你将很难弄清楚为什么雪佛兰的形象有时候是第二页的小行李箱。