Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 数据访问层-静态列表对象和缓存_Asp.net Mvc_Caching_Data Access Layer - Fatal编程技术网

Asp.net mvc 数据访问层-静态列表对象和缓存

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>();

我正在使用.NETMVC开发一个站点

我有一个数据访问层,它基本上由静态列表对象组成,这些对象是从数据库中的数据创建的

重建此数据的方法首先清除所有列表对象。一旦它们为空,则添加数据。下面是我使用的列表之一的示例。这是一种生成所有英国邮政编码的方法。在我的应用程序中,大约有50种类似的方法可以返回各种信息,例如城镇、地区、成员、电子邮件等

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中内置的缓存功能,您可以更轻松地完成所有操作

    我有没有办法说“当 重建正在进行,请等待 在接受请求之前完成”

    常见模式如下所示:

  • 您可以从数据层请求数据

  • 如果Datlayer看到缓存中有数据,那么它将为缓存中的数据提供服务 如果缓存中没有数据,则从db请求数据并将其放入缓存。之后,它被送达客户

  • 清除缓存时有一些规则(CacheDependency和Timeout)


    最简单的解决方案是坚持这种模式:这样,第一个请求将命中数据库,其他请求将从缓存中得到服务。您可以通过实现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;