在过去,我已经锁定了访问HttpRuntime.Cache机制。 我不确定我过去是否真的研究过这个问题,盲人用锁把它围起来。
您认为这是否真的有必要?
答案 0 :(得分:10)
本文建议使用锁:
http://msdn.microsoft.com/en-us/magazine/cc500561.aspx
引用:
问题是,如果你有一个 查询需要30秒而且你是 每秒执行一次页面 填充的时间 缓存项目,其他29个请求将 进来,所有这些都将尝试 使用自己的缓存项填充缓存项 查询数据库。要解决这个问题 问题,你可以添加一个线程锁 停止其他页面执行 从数据库中请求数据。
以下是他们的代码段:
// check for cached results
object cachedResults = ctx.Cache["PersonList"];
ArrayList results = new ArrayList();
if (cachedResults == null)
{
// lock this section of the code
// while we populate the list
lock(lockObject)
{
cachedResults = ctx.Cache["PersonList"];
// only populate if list was not populated by
// another thread while this thread was waiting
if (cachedResults == null)
{
cachedResults = ...
ctx.Cache["PersonList"] = cachedResults;
}
}
}
我没有测试过这段代码,但我很想听听有人在生产环境中评估过这种方法。
答案 1 :(得分:8)
根据此文档http://msdn.microsoft.com/en-us/library/system.web.caching.cache(VS.80).aspx,对缓存对象的访问是线程安全的。 至于你存储在缓存中的对象,线程的安全性必须来自其他地方。
答案 2 :(得分:2)
我认为不需要使用锁来包装对HttpRuntime.Cache属性的访问,因为.Cache属性是静态的,也是线程安全的。
有许多不同的方法可以访问Cache对象(HttpRuntime.Cache,HttpContext.Current.Cache,Page.Cache等)。它们都访问相同的Cache对象,因为每个Application Domain只有一个Cache对象,因为它实际上是一个线程安全的Singleton对象。
答案 3 :(得分:2)
我认为锁定不是以下问题的答案,特别是在生产环境中,您有多台运行应用程序的服务器。
问题在于,如果你的查询需要30秒而且你每秒都在执行一次页面,那么在填充缓存项目所需的时间内,其他29个请求将会进入,所有这些请求都会尝试使用自己的查询将缓存项填充到数据库。要解决此问题,您可以添加线程锁以阻止其他页面执行从数据库请求数据。