English 中文(简体)
锁定 HttpRuntime.Cache 以进行惰性加载
原标题:
  • 时间:2009-01-15 17:35:06
  •  标签:

我们运行 .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。

最佳回答

据我所知,缓存对象是线程安全的,因此您不需要锁定。

问题回答

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

你的代码可能会让你认为你会在缓存了一天的情况下一直拥有该数据,并且你的最后一行代码总是会提供给你这个数据,但事实并非如此。正如其他人所说,缓存操作是同步的,所以你不应该在那个点上锁定。

请点击这里查看正确的操作方式

线程安全。这意味着所有其他进程都将永远等待您的代码完成吗?

线程安全意味着您可以确保检索的项目不会在您读取该项目时同时被缓存更新“切割一半”或部分破坏。

item = cache.Get(key);

但是在那之后,任何你所做的事情——另一个线程可以对缓存(或任何其他共享资源)进行操作。如果你想根据你获取的项目是否为空来对缓存进行某些操作,我不能百分之百确定它是否已经被你自己代码的另一个实例固定,它正好比另一个读者更快地处于相同页面的同一页上线动汽车杂志。

你需要一些不幸。其他进程在几行代码之外打扰相同缓存对象的风险是非原子性的,随机很小。但如果发生,你会很难弄清楚为什么雪佛兰车的图像有时会变成第二页上的小手提箱。





相关问题
热门标签