20

过去,我锁定了访问 HttpRuntime.Cache 机制。我不确定我过去是否真的研究过这个问题并且盲目地用锁包围了它。

你觉得这真的有必要吗?

4

4 回答 4

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

我没有测试过这段代码,但我很想听听有人在生产环境中评估过这种方法。

于 2010-02-25T00:07:39.717 回答
8

根据此文档http://msdn.microsoft.com/en-us/library/system.web.caching.cache(VS.80).aspx访问缓存对象是线程安全的。至于您存储在缓存中的对象,线程安全必须来自其他地方。

于 2009-04-16T08:19:24.123 回答
2

我认为没有必要用锁来包装对 HttpRuntime.Cache 属性的访问,因为 .Cache 属性是静态的并且也是线程安全的。

访问 Cache 对象的方式有很多种(HttpRuntime.Cache、HttpContext.Current.Cache、Page.Cache 等)。它们都访问同一个 Cache 对象,因为每个应用程序域只有一个 Cache 对象,因为它实际上是一个线程安全的 Singleton 对象。

于 2009-04-16T08:32:38.587 回答
2

我不认为锁定是下面问题的答案,尤其是在生产环境中,您有多个服务器运行您的应用程序。

问题是,如果您有一个需要 30 秒的查询,并且您每秒都在执行该页面,那么在填充缓存项所需的时间内,将会有 29 个其他请求进入,所有这些请求都将尝试填充缓存项与他们自己对数据库的查询。为了解决这个问题,您可以添加一个线程锁来阻止其他页面执行从数据库中请求数据。

于 2011-07-06T23:58:37.633 回答