ConfigurationManager.AppSettings [Key]每次都从web.config文件中读取吗?

The*_*ght 68 c# asp.net configurationmanager web-config

我只是想知道ConfigurationManager.AppSettings [Key]是如何工作的?

每次需要密钥时它是否从物理文件中读取?

如果是这样,我应该在缓存中读取web.config的所有应用程序设置,然后从中读取吗?

或者ASP.NET或IIS只在application_startup加载web.config文件一次.

如何验证每次读取是否访问物理文件?

如果我更改了web.config,IIS将重新启动我的应用程序,因此无法以这种方式进行验证.

谢谢,

das*_*ash 85

它在首次访问属性时被缓存,因此每次请求值时它都不会从物理文件中读取.这就是为什么有必要重新启动Windows应用程序(或刷新配置)以获取最新值,以及为什么在编辑web.config时ASP.Net应用程序会自动重新启动.为什么ASP.Net是硬连线重启,请参阅答案中的参考资料如何在修改web.config时阻止ASP.NET应用程序重新启动.

我们可以使用ILSpy验证这一点,并查看System.Configuration的内部:

public static NameValueCollection AppSettings
{
    get
    {
        object section = ConfigurationManager.GetSection("appSettings");
        if (section == null || !(section is NameValueCollection))
        {
            throw new ConfigurationErrorsException(SR.GetString("Config_appsettings_declaration_invalid"));
        }
        return (NameValueCollection)section;
    }
}
Run Code Online (Sandbox Code Playgroud)

起初,这确实看起来每次都会获得该部分.看看GetSection:

public static object GetSection(string sectionName)
{
    if (string.IsNullOrEmpty(sectionName))
    {
        return null;
    }
    ConfigurationManager.PrepareConfigSystem();
    return ConfigurationManager.s_configSystem.GetSection(sectionName);
}
Run Code Online (Sandbox Code Playgroud)

这里的关键线是PrepareConfigSystem()方法; 这初始化IInternalConfigSystemConfigurationManager持有的字段的实例- 具体类型是ClientConfigurationSystem

作为此加载的一部分,将实例化Configuration类的实例.此类实际上是配置文件的对象表示,并且似乎由ClientConfigurationSystem的ClientConfigurationHost属性保存在静态字段中 - 因此它被缓存.

您可以通过执行以下操作(在Windows窗体或WPF应用程序中)凭经验测试:

  1. 开始你的应用程序
  2. 访问app.config中的值
  3. 对app.config进行更改
  4. 检查新值是否存在
  5. 呼叫 ConfigurationManager.RefreshSection("appSettings")
  6. 检查新值是否存在.

事实上,如果我只是阅读关于RefreshSection方法的评论,我本可以节省一些时间:-)

/// <summary>Refreshes the named section so the next time that it is retrieved it will be re-read from disk.</summary>
/// <param name="sectionName">The configuration section name or the configuration path and section name of the section to refresh.</param>
Run Code Online (Sandbox Code Playgroud)


Bel*_*gix 7

简单的答案是否定的,它并不总是从文件中读取它.有些人建议如果文件被更改,那么IIS会执行重启但不总是!如果您想保证从文件而不是缓存中读取最新值,则需要调用以下内容:

ConfigurationManager.RefreshSection("appSettings");
string fromFile = ConfigurationManager.AppSettings.Get(key) ?? string.Empty;
Run Code Online (Sandbox Code Playgroud)

我在我的代码中使用的一个例子:

/// ======================================================================================
/// <summary>
/// Refreshes the settings from disk and returns the specific setting so guarantees the
/// value is up to date at the expense of disk I/O.
/// </summary>
/// <param name="key">The setting key to return.</param>
/// <remarks>This method does involve disk I/O so should not be used in loops etc.</remarks>
/// <returns>The setting value or an empty string if not found.</returns>
/// ======================================================================================
private string RefreshFromDiskAndGetSetting(string key)
{
    // Always read from the disk to get the latest setting, this will add some overhead but
    // because this is done so infrequently it shouldn't cause any real performance issues
    ConfigurationManager.RefreshSection("appSettings");
    return GetCachedSetting(key);
}

/// ======================================================================================
/// <summary>
/// Retrieves the setting from cache so CANNOT guarantees the value is up to date but
/// does not involve disk I/O so can be called frequently.
/// </summary>
/// <param name="key">The setting key to return.</param>
/// <remarks>This method cannot guarantee the setting is up to date.</remarks>
/// <returns>The setting value or an empty string if not found.</returns>
/// ======================================================================================
private string GetCachedSetting(string key)
{
    return ConfigurationManager.AppSettings.Get(key) ?? string.Empty;
}
Run Code Online (Sandbox Code Playgroud)

这使您可以非常轻松地选择(以及在阅读代码时)是否每次都获得最新值,或者如果您不希望从应用程序启动时更改值.