简体   繁体   English

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

[英]Does ConfigurationManager.AppSettings[Key] read from the web.config file each time?

I'm wondering how the ConfigurationManager.AppSettings[Key] works.我想知道ConfigurationManager.AppSettings[Key]是如何工作的。

Does it read from the physical file each time I need a key?每次我需要密钥时,它是否从物理文件中读取? If so, should I be reading all the app settings of my web.config in a cache and then read from it?如果是这样,我是否应该在缓存中读取 web.config 的所有应用程序设置,然后从中读取?

Or does ASP.NET or IIS load the web.config file only once at application startup?或者 ASP.NET 或 IIS 在应用程序启动时只加载一次 web.config 文件?

How do I verify whether the physical file is accessed by each read?如何验证每次读取是否访问物理文件? If I change the web.config, IIS restarts my application, so I can't verify it that way.如果我更改 web.config,IIS 会重新启动我的应用程序,因此我无法以这种方式验证它。

It gets cached, on first access of a property, so it does not read from the physical file each time you ask for a value.它在第一次访问属性时被缓存,因此每次您请求一个值时它都不会从物理文件中读取。 This is why it is necessary to restart an Windows app (or Refresh the config) to get the latest value, and why an ASP.Net app automatically restarts when you edit web.config.这就是为什么有必要重新启动 Windows 应用程序(或刷新配置)以获取最新值,以及当您编辑 web.config 时 ASP.Net 应用程序自动重新启动的原因。 Why ASP.Net is hard wired to restart is discussed in the references in the answer How to prevent an ASP.NET application restarting when the web.config is modified .为什么 ASP.Net 硬连线重启在答案中的参考文献中讨论如何在修改 web.config 时防止 ASP.NET 应用程序重启

We can verify this using ILSpy and looking at the internals of System.Configuration:我们可以使用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;
    }
}

At first, this does indeed look like it will get the section every time.起初,这确实看起来每次都会得到该部分。 Looking at GetSection:查看 GetSection:

public static object GetSection(string sectionName)
{
    if (string.IsNullOrEmpty(sectionName))
    {
        return null;
    }
    ConfigurationManager.PrepareConfigSystem();
    return ConfigurationManager.s_configSystem.GetSection(sectionName);
}

The critical line here is the PrepareConfigSystem() method;这里的关键是PrepareConfigSystem()方法; this initializes an instance of the IInternalConfigSystem field held by the ConfigurationManager - the concrete type is ClientConfigurationSystem这将初始化由 ConfigurationManager 持有的IInternalConfigSystem字段的实例 - 具体类型是ClientConfigurationSystem

As part of this load, an instance of the Configuration class is instantiated.作为此加载的一部分,将实例化Configuration类的一个实例。 This class is effectively an object representation of the config file, and appears to be held by the ClientConfigurationSystem's ClientConfigurationHost property in a static field - hence it is cached.这个类实际上是配置文件的对象表示,并且似乎由静态字段中的 ClientConfigurationSystem 的 ClientConfigurationHost 属性保存 - 因此它被缓存。

You could test this empirically by doing the following (in a Windows Form or WPF app):您可以通过执行以下操作(在 Windows 窗体或 WPF 应用程序中)凭经验对此进行测试:

  1. Starting your App up启动您的应用程序
  2. Access a value in app.config访问 app.config 中的值
  3. Make a change to app.config对 app.config 进行更改
  4. Check to see whether the new value is present检查新值是否存在
  5. Call ConfigurationManager.RefreshSection("appSettings")调用ConfigurationManager.RefreshSection("appSettings")
  6. Check to see if the new value is present.检查新值是否存在。

In fact, I could have saved myself some time if I'd just read the comment on the RefreshSection method :-)事实上,如果我只是阅读有关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>

The simple answer is no, it doesn't always read it from the file.简单的答案是否定的,它并不总是从文件中读取它。 As some have suggested if the file is changed then IIS performs a restart but not always!正如一些人所建议的,如果文件被更改,IIS 会执行重新启动,但并非总是如此! If you want to guarantee that you are reading the very latest value from the file and not the cache you need to call something like this:如果你想保证你从文件而不是缓存中读取最新的值,你需要调用这样的东西:

ConfigurationManager.RefreshSection("appSettings");
string fromFile = ConfigurationManager.AppSettings.Get(key) ?? string.Empty;

And an example I use in my code:以及我在代码中使用的示例:

/// ======================================================================================
/// <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;
}

This allows you to very easily choose (and when reading code see) whether you are getting the latest value each time or if you don't expect the value to change from when the application starts.这使您可以非常轻松地选择(并在阅读代码时查看)是每次获取最新值,还是不希望应用程序启动时该值发生变化。

var file = new FileInfo(@"\\MyConfigFilePath\Web.config");

DateTime first  = file.LastAccessTime;

string fn = ConfigurationManager.AppSettings["FirstName"];
Thread.Sleep(2000);

DateTime second = file.LastAccessTime;

string sn = ConfigurationManager.AppSettings["Surname"];
Thread.Sleep(2000);

DateTime third = file.LastAccessTime;

All show the same LastAccessTime which means it's cached at startup.所有都显示相同的 LastAccessTime,这意味着它在启动时被缓存。

string fn1 = ConfigurationManager.AppSettings["FirstName"];
Thread.Sleep(2000);

DateTime fourth = file.LastAccessTime;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 努力在 ASP .NET 中使用 ConfigurationManager.AppSettings[“key”] 从 web.config 文件中读取值 - Struggling to read value from web.config file using ConfigurationManager.AppSettings[“key”] in ASP .NET ConfigurationManager.AppSettings 使用另一个配置文件 - ConfigurationManager.AppSettings use another config file ConfigurationManager.AppSettings不能用于以编程方式创建的App.config文件 - ConfigurationManager.AppSettings does not work with an App.config file created programmatically 程序包安装的可执行文件不会从.config文件加载ConfigurationManager.AppSettings - Package installed executable doesn't load ConfigurationManager.AppSettings from .config file 从web.config中的appsettings中读取文件属性 - Read file attribute from appsettings from web.config 使用WebConfigurationManager从Web.config文件中读取appSettings部分 - Read appSettings section from Web.config file using WebConfigurationManager ConfigurationManager.AppSettings仅读取第一个键 - ConfigurationManager.AppSettings reading only first key ConfigurationManager.AppSettings[key] 始终为 null - ConfigurationManager.AppSettings[key] is always null 为什么在ConfigurationManager.AppSettings [key]上调用.ToString()? - Why call .ToString() on ConfigurationManager.AppSettings[key]? ConfigurationManager.AppSettings是做什么的? - What does ConfigurationManager.AppSettings do?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM