Asp.net mvc 数据访问层-静态列表对象和缓存
我正在使用.NETMVC开发一个站点 我有一个数据访问层,它基本上由静态列表对象组成,这些对象是从数据库中的数据创建的 重建此数据的方法首先清除所有列表对象。一旦它们为空,则添加数据。下面是我使用的列表之一的示例。这是一种生成所有英国邮政编码的方法。在我的应用程序中,大约有50种类似的方法可以返回各种信息,例如城镇、地区、成员、电子邮件等Asp.net mvc 数据访问层-静态列表对象和缓存,asp.net-mvc,caching,data-access-layer,Asp.net Mvc,Caching,Data Access Layer,我正在使用.NETMVC开发一个站点 我有一个数据访问层,它基本上由静态列表对象组成,这些对象是从数据库中的数据创建的 重建此数据的方法首先清除所有列表对象。一旦它们为空,则添加数据。下面是我使用的列表之一的示例。这是一种生成所有英国邮政编码的方法。在我的应用程序中,大约有50种类似的方法可以返回各种信息,例如城镇、地区、成员、电子邮件等 public static List<PostCode> AllPostCodes = new List<PostCode>();
public static List<PostCode> AllPostCodes = new List<PostCode>();
一旦抛出此异常,应用程序死亡,所有用户都会受到影响。我必须重新启动服务器才能修复它
我有两个问题
truegilly当其他线程尝试使用列表时,必须确保列表没有被一个线程修改。即使使用ASP.NET缓存,这也是一个问题,因为集合不是线程安全的。一种方法是使用SynchronizedCollection而不是列表。然后确保在访问集合时使用如下代码:
lock (synchronizedCollection.SyncRoot) {
synchronizedCollection.Clear();
etc...
}
在读取集合时,还必须使用锁定。如果要对其进行枚举,则可能应该在进行此操作之前制作一个副本,因为您不希望长时间锁定。例如:
List<whatever> tempCollection;
lock (synchrnonizedCollection.SyncRoot) {
tempCollection = new List<whatever>(synchronizedCollection);
}
//use temp collection to access cached data
列表集合;
锁(synchrnonizedCollection.SyncRoot){
tempCollection=新列表(synchronizedCollection);
}
//使用临时集合访问缓存数据
另一个选项是创建一个ThreadSafeList类,该类在内部使用锁定使列表对象本身具有线程安全性
1如果我使用缓存而不是
静态对象这会有帮助吗
是的,通过ASP.NET中内置的缓存功能,您可以更轻松地完成所有操作
我有没有办法说“当
重建正在进行,请等待
在接受请求之前完成”
常见模式如下所示:
最简单的解决方案是坚持这种模式:这样,第一个请求将命中数据库,其他请求将从缓存中得到服务。您可以通过实现SQLCacheDependency来触发刷新。我同意Tom的观点,您必须进行同步才能使其正常工作。提高性能的一个方法是在实际从数据库接收到新值之前不清除列表:
// Modify your function to return a new list instead of filling the existing one.
public static List<PostCode> GetAllPostCodes()
{
List<PostCode> temp = new List<PostCode>();
...
return temp;
}
//修改函数以返回新列表,而不是填充现有列表。
公共静态列表GetAllPostCodes()
{
列表温度=新列表();
...
返回温度;
}
当您重建数据时:
List<PostCode> temp = GetAllPostCodes();
AllPostCodes = temp;
List temp=GetAllPostCodes();
所有邮政编码=临时;
这样可以确保在执行GetAllPostCodes()时缓存列表仍然有效。它还有一个优点,即您可以使用只读列表,这使同步更容易。在您的情况下,您需要每一小时刷新一次数据 1) 它应该使用绝对过期设置为1小时的缓存,因此它每1小时过期一次。在使用缓存之前,通过执行NULL检查来检查它。如果它为NULL,则从DB获取数据并填充缓存
2) 使用上述方法的缺点是数据可能会过时1小时。因此,如果您希望在任何时候更新最多的数据,请使用SQLCacheDependency(PUSH)。因此,每当select命令u r using发生更改时,将使用更新的数据从数据库中刷新缓存。最正确的解决方案是避免使用不好的静态方法。我是说,总是很糟糕。即使你认为它是好的,也要三思而后行,因为它很糟糕。如果您使用它们,请记住web应用程序请求可能会同时在不同的线程上进行。然后,了解静态数据和线程,并再次决定是否需要它们。我将实施您的建议,一旦到位如果我遇到任何问题,我将查看同步和线程注释谢谢
// Modify your function to return a new list instead of filling the existing one.
public static List<PostCode> GetAllPostCodes()
{
List<PostCode> temp = new List<PostCode>();
...
return temp;
}
List<PostCode> temp = GetAllPostCodes();
AllPostCodes = temp;