为ASP.NET中的第一个访问者设置缓存对象

为ASP.NET中的第一个访问者设置缓存对象,asp.net,multithreading,caching,locking,Asp.net,Multithreading,Caching,Locking,我有一个网站,它将从数据库中检索一些重数据,并将其存储到缓存对象中。但是,在高峰时间,如果缓存对象过期,并且所有用户同时检索数据,我的网站将变得非常慢(CPU 100%),网站与数据库之间的连接将超时。因此,缓存对象将变为空 我的临时解决方案是,每次缓存对象过期时。我必须通过将所有用户重定向到静态页面来停止所有用户。然后清除缓存对象并以管理员身份访问页面(目前仅允许管理员访问)以生成缓存对象。之后,我将再次启用该页面,用户可以像往常一样访问该页面 我在想,是否有可能在缓存对象过期时创建缓存对象,

我有一个网站,它将从数据库中检索一些重数据,并将其存储到缓存对象中。但是,在高峰时间,如果缓存对象过期,并且所有用户同时检索数据,我的网站将变得非常慢(CPU 100%),网站与数据库之间的连接将超时。因此,缓存对象将变为空

我的临时解决方案是,每次缓存对象过期时。我必须通过将所有用户重定向到静态页面来停止所有用户。然后清除缓存对象并以管理员身份访问页面(目前仅允许管理员访问)以生成缓存对象。之后,我将再次启用该页面,用户可以像往常一样访问该页面

我在想,是否有可能在缓存对象过期时创建缓存对象,仅当第一个访问者访问页面时才会创建缓存对象(在高峰时间,最多可能有50个用户同时访问页面),而访问页面的剩余用户必须等到创建缓存对象后再创建(停止它们以调用创建缓存对象模块)

当前的工作方式是每次用户访问此页面时,它都会检查缓存对象。如果为空,则它将从数据库中检索
HeavyData

if (Cache[ID] == null)
    {
        HeavyData = RetrieveHeavyDataFromDatabase(); // retrieve data from db 
        Cache.Insert(ID, HeavyData, null, DateTime.Now.AddMinutes(720)), System.Web.Caching.Cache.NoSlidingExpiration);
    }

问题可能是多个请求正在尝试重新创建缓存

只需在你的单例周围添加一个锁对象和一个if-lock-if包装器。这将仍然保留每个请求,直到缓存被填充,但将确保只有一个请求将进入繁重的进程


您应该在其周围包装一个lock语句。它将确保只有一个线程可以执行繁重的检索

static Object lockObject = new Object();
lock(lockObject)
{
    if (Cache[ID] == null)
    {
        HeavyData = RetrieveHeavyDataFromDatabase(); // retrieve data from db 
        Cache.Insert(ID, HeavyData, null, DateTime.Now.AddMinutes(720)), System.Web.Caching.Cache.NoSlidingExpiration);
    }
}

谢谢!我想把你们标记为答案,不过有人在你们之前回答了=(您好@My2ndLovE,哦,没关系。解决方案非常相似。为了消除幸运用户重建缓存的繁重请求,您可以添加一个带有缓存过期回调的辅助缓存项,该回调将在重载缓存项过期之前重新填充该缓存项。这将作为后台进程进行,并且与用户r无关equests.见下文。。
static Object lockObject = new Object();
lock(lockObject)
{
    if (Cache[ID] == null)
    {
        HeavyData = RetrieveHeavyDataFromDatabase(); // retrieve data from db 
        Cache.Insert(ID, HeavyData, null, DateTime.Now.AddMinutes(720)), System.Web.Caching.Cache.NoSlidingExpiration);
    }
}