在以下场景中,在MVC应用程序中使用静态字段是否存在任何风险?

时间:2014-04-23 15:42:41

标签: c# asp.net-mvc asp.net-mvc-4 static

我有一个检测脏话的验证注释。我的脏话是在数据库中,但我想将它们保存在内存中以避免不必要的查询。我想在验证注释类中添加一个静态的脏字列表(作为普通的旧字符串),并在应用程序运行期间第一次使用验证时根据我在数据库中的内容填充它。使用此类解决方案是否存在任何风险?

P.S。我真的不在乎是否有人在应用程序运行期间向数据库添加了更多单词。有一个不完整的列表“直到下次重启”已经足够了(该应用程序将每天重新启动)。

2 个答案:

答案 0 :(得分:4)

如果将其放置到HttpContext.Current.Cache并且有效期,那会更好。然后,这些数据在缓存中过期时将被删除,然后您可以重新加载实际的最新数据。在这种情况下,数据的实际情况将比静态列表更好。

您可以编写此类代码:

public static List<string> SwearWords
{
    get
    {
        List<string> items = HttpContext.Current.Cache["SwearWords"] as List<string>()
        if (items == null)
        {
            items = LoadThemFromDB();
            HttpContext.Current.Cache.Insert("SwearWords", 
                items, 
                null, 
                DateTime.Now.AddMinutes(10),
                Cache.NoSlidingExpiration);
        }
        return items;
    }
}

然后,如果您第一次访问此属性 - 它将从DB和缓存加载它们10分钟。十分钟后,它将从缓存中删除,如果在它之后再次访问它 - 它将加载最新数据并再次缓存它们。

如果是静态列表,您需要手动刷新\更新,以防数据库中的SwearWords更新。

您还应该记住,然后IIS在20分钟不活动后停止应用程序池。因此,如果20分钟内没有任何用户,它将自动重启。此缓存\静态列表也将在AppDomain

中清除

其次是 Markus 注释 - 这里是带有双重检查的相同示例,如果同时由多个线程调用它,将避免重复调用LoadThemFromDB

private static readonly object _swearWordsLockObj = new object();

public static List<string> SwearWords
{
    get
    {
        List<string> items = HttpContext.Current.Cache["SwearWords"] as List<string>()
        if (items == null)
        {
            lock(_swearWordsLockObj)
            {
                items = HttpContext.Current.Cache["SwearWords"] as List<string>()
                if (items == null)
                {
                    items = LoadThemFromDB();
                    HttpContext.Current.Cache.Insert("SwearWords", 
                        items, 
                        null, 
                        DateTime.Now.AddMinutes(10),
                        Cache.NoSlidingExpiration);
                }
            }
        }
        return items;
    }
}

此代码名为Double checked Locking - http://en.wikipedia.org/wiki/Double-checked_locking

答案 1 :(得分:1)

只要您的发誓单词列表可以安全地阅读。

考虑使用List<T>,可以同时从多个线程读取,只要没有写入。

来自the documentation

  

只要未修改集合,List<T>可以同时支持多个阅读器。