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