是否需要锁定这些静态应用程序属性?

本文关键字:静态 应用程序 属性 锁定 是否 | 更新日期: 2023-09-27 18:14:05

在我的web应用程序中,我在Application_Start期间从外部配置文件中读取一些设置,然后通过应用程序的许多方法访问它们:

namespace Common
{
    public static class CommonConfigSettings
    {
        public static string DataSource { get; set; }
        public static string DatabaseName { get; set; }
        public static string DatabaseUserName { get; set; }
        public static string DatabasePassword { get; set; }
    }
}

Application_Start期间,这些从XML文件中读取到静态变量:

DataSource = els.FirstOrDefault(item => item.Attribute("key").Value == "DataSource").Attribute("value").Value;
DatabaseName = els.FirstOrDefault(item => item.Attribute("key").Value == "DatabaseName").Attribute("value").Value;
DatabaseUserName = els.FirstOrDefault(item => item.Attribute("key").Value == "DatabaseUserName").Attribute("value").Value;
DatabasePassword = els.FirstOrDefault(item => item.Attribute("key").Value == "DatabasePassword").Attribute("value").Value;

在应用程序中,它们的用法如下:

myConn.ConnectionString = string.Format("Persist Security Info=False; User ID={0}; Password={1}; Initial Catalog={2}; Data Source={3}; Connection Timeout=60", 
    CommonConfigSettings.DatabaseUserName, 
    CommonConfigSettings.DatabasePassword, 
    CommonConfigSettings.DatabaseName, 
    CommonConfigSettings.DataSource);

在任何时间点都不会写入Application_Start之后的静态值-它们只会被读回来(尽管可能同时由2个以上的人)。也没有静态方法,只有属性。我读了关于锁和线程安全在这里和这里,但只有困惑自己。我应该在这些值上实现锁吗?如果是的话,在什么时候?

是否需要锁定这些静态应用程序属性?

如果您绝对确定这些属性只写入一次(并且在所有读操作之前),则不需要锁定。

问题是:它会永远是这样吗?如果你需要在运行时替换这个数据库访问信息,你就会遇到非原子操作的问题(例如,如果写线程在正确/"错误"的时间被中断,读取一个新的数据库用户名和旧密码)。也许提供一个方法在单个结构中返回所有需要的数据会更好。如果将来需要的话,可以为这个方法提供线程锁定机制。
public struct DatabaseAccessData
{
    public string DataSource { get; set; }
    public string DatabaseName { get; set; }
    public string DatabaseUserName { get; set; }
    public string DatabasePassword { get; set; }
}
public static class CommonConfigSettings
{        
    private static string DataSource { get; set; }
    private static string DatabaseName { get; set; }
    private static string DatabaseUserName { get; set; }
    private static string DatabasePassword { get; set; }
    public static void SetDatabaseAccessData(DatabaseAccessData data)
    {
        DataSource = data.DataSource;
        DatabaseName = data.DatabaseName;
        DatabaseUserName = data.DatabaseUserName;
        DatabasePassword = data.DatabasePassword;
    }
    public static DatabaseAccessData GetDatabaseAccessData()
    {
        return new DatabaseAccessData
        {
            DataSource = DataSource,
            DatabaseName = DatabaseName,
            DatabaseUserName = DatabaseUserName,
            DatabasePassword = DatabasePassword
        };
    }

我要说的是,在这种情况下,我不是"静态"的粉丝。如果你的一些类依赖于公共配置设置,你应该通过构造函数参数或属性传递CommonConfigSettings的实例给它们(参见"依赖注入")。我更喜欢前者,因为它更严格;你不能忘记传递一个重要的依赖项。