3

我们有一个运行 .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

4 回答 4

10

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

于 2009-01-15T17:40:33.063 回答
5

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

于 2009-01-15T17:45:59.107 回答
1

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

看看这里的正确方法

于 2009-07-11T17:25:20.937 回答
0

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

线程安全是您可以确保在读取项目的同时,您获取的项目不会被“切成两半”或因缓存更新而部分拆除。

item = cache.Get(key);

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

你需要一些坏运气。在几行代码中,其他进程干扰同一个非原子缓存对象的风险随机小。但如果发生这种情况,您将很难弄清楚为什么雪佛兰的形象有时是第二页中的小手提箱。

于 2015-05-23T08:59:34.780 回答