c# - net - ¿Se lee ConfigurationManager.AppSettings[Key] cada vez desde el archivo web.config?
read web config c# (3)
La respuesta simple es no, no siempre lo lee del archivo. Como algunos han sugerido si el archivo se cambia, IIS realiza un reinicio pero no siempre. Si quiere garantizar que está leyendo el valor más reciente del archivo y no del caché, debe llamar a algo como esto:
ConfigurationManager.RefreshSection("appSettings");
string fromFile = ConfigurationManager.AppSettings.Get(key) ?? string.Empty;
Y un ejemplo que uso en mi código:
/// ======================================================================================
/// <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;
}
Esto le permite elegir muy fácilmente (y al leer el código ver) si está obteniendo el último valor cada vez o si no espera que el valor cambie desde el momento en que se inicia la aplicación.
Me pregunto cómo funciona ConfigurationManager.AppSettings [Key]?
¿Lee del archivo físico cada vez que necesito una clave?
Si es así, ¿debería leer todas las configuraciones de la aplicación de mi web.config en un caché y luego leer de ella?
O ASP.NET o IIS carga el archivo web.config en application_startup y solo una vez.
¿Cómo verificar si cada lectura tiene acceso al archivo físico?
Si cambio el archivo web.config, IIS reinicia mi aplicación, por lo que no puedo verificarlo de esa manera.
Gracias,
Se almacena en caché, en el primer acceso de una propiedad, por lo que no se lee en el archivo físico cada vez que solicita un valor. Es por eso que es necesario reiniciar una aplicación de Windows (o Refresh la configuración) para obtener el último valor, y por qué una aplicación ASP.Net se reinicia automáticamente cuando edita web.config. El por qué ASP.Net está cableado para reiniciar se trata en las referencias en la respuesta Cómo evitar que una aplicación ASP.NET se reinicie cuando se modifique web.config .
Podemos verificar esto usando ILSpy y mirando las ILSpy internas de 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;
}
}
Al principio, parece que obtendrá la sección todo el tiempo. Mirando GetSection:
public static object GetSection(string sectionName)
{
if (string.IsNullOrEmpty(sectionName))
{
return null;
}
ConfigurationManager.PrepareConfigSystem();
return ConfigurationManager.s_configSystem.GetSection(sectionName);
}
La línea crítica aquí es el método PrepareConfigSystem()
; esto inicializa una instancia del campo IInternalConfigSystem
en el ConfigurationManager - el tipo concreto es ClientConfigurationSystem
Como parte de esta carga, se instancia una instancia de la clase de Configuration . Esta clase es efectivamente una representación de objeto del archivo de configuración, y parece que la propiedad ClientConfigurationHost de ClientConfigurationSystem la mantiene en un campo estático, por lo que se almacena en caché.
Puede probar esto empíricamente haciendo lo siguiente (en una aplicación Windows Form o WPF):
- Iniciando tu aplicación
- Acceda a un valor en app.config
- Haz un cambio en app.config
- Verifique si el nuevo valor está presente
- Llamar a
ConfigurationManager.RefreshSection("appSettings")
- Verifique si el nuevo valor está presente.
De hecho, podría haberme ahorrado algo de tiempo si hubiera leído el comentario sobre el método Refresh :-)
/// <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>
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;
Todos muestran el mismo LastAccessTime, lo que significa que está en la memoria caché al inicio.
string fn1 = ConfigurationManager.AppSettings["FirstName"];
Thread.Sleep(2000);
DateTime fourth = file.LastAccessTime;