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

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

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

附言我真的不在乎是否有人在应用程序运行期间向数据库添加了更多单词。有一个不完整的列表“直到下次重启”就足够了(无论如何,应用程序每天都会重启)。

最佳答案

如果您将其放置在具有一定有效期的 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;
    }
}

然后,如果您第一次访问此属性 - 它将从数据库中加载它们并缓存 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;
    }
}

此代码名为双重检查锁定 - http://en.wikipedia.org/wiki/Double-checked_locking

关于c# - 在以下场景中,在 MVC 应用程序中使用静态字段是否有任何风险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23249246/

相关文章:

c# - MVC Dropdownlist 未验证并发出警告

c# - ASP.NET MVC @Html.LabelFor(model => model.Name) 助手

c# - 在 C# 中使用 SQLite.NET 获取最后插入 ID

entity-framework - 模型中的多个图表与一个大型 .EDMX 与多个 .EDMX

javascript - 网站的 navigator.connection.type 的替代方案

asp.net-mvc - ASP.NET MVC 和 LINQ 一般问题

javascript - 通过 SelectBox 的下一个上一个按钮

c# - 比较具有毫秒精度的日期时间

c# - IronPython 调用 TryGetMember 而不是 TryInvokeMember

c# - 从 ASP.NET MVC Controller 中删除功能