2012-11-13 16 views
64

Ich frage mich nur, wie die ConfigurationManager.AppSettings [Key] funktioniert?Wird ConfigurationManager.AppSettings [Key] jedes Mal aus der Datei "web.config" gelesen?

Liest es jedes Mal aus der physischen Datei, wenn ich einen Schlüssel brauche?

Wenn ja, sollte ich alle App-Einstellungen meiner web.config in einem Cache lesen und dann daraus lesen?

Oder ASP.NET oder IIS lädt die web.config-Datei bei application_startup und nur einmal.

Wie kann überprüft werden, ob auf die physische Datei bei jedem Lesen zugegriffen wird?

Wenn ich die web.config ändere, startet IIS meine Anwendung neu, so kann es nicht auf diese Weise verifizieren.

Danke,

Antwort

78

Es wird zwischengespeichert, beim ersten Zugriff einer Immobilie, so dass es nicht von der physischen Datei jedes Mal, wenn Sie für einen Wert lesen fragen. Aus diesem Grund ist es notwendig, eine Windows-App (oder Refresh die Konfig) neu zu starten, um den neuesten Wert zu erhalten, und warum eine ASP.Net-Anwendung beim Bearbeiten von web.config automatisch neu gestartet wird. Warum ASP.Net zum Neustart fest verdrahtet ist, wird in den Referenzen in der Antwort How to prevent an ASP.NET application restarting when the web.config is modified diskutiert.

Wir können auf die Interna von System.Configuration dies mit ILSpy und auf der Suche überprüfen:

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

Zunächst dies in der Tat sieht wie es jedes Mal, wenn der Abschnitt erhalten. Mit Blick auf GetSection:

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

Die kritische Linie ist hier die PrepareConfigSystem() Methode; Dies initialisiert eine Instanz des Feldes IInternalConfigSystem des ConfigurationManagers - der konkrete Typ ist ClientConfigurationSystem

Als Teil dieses Ladens wird eine Instanz der Klasse Configuration instanziiert. Diese Klasse ist effektiv eine Objektdarstellung der Konfigurationsdatei und wird anscheinend von der ClientConfigurationHost-Eigenschaft des ClientConfigurationSystems in einem statischen Feld gehalten - daher wird sie zwischengespeichert.

Sie könnten dies empirisch testen, indem Sie die folgenden Schritte (in einem Windows Form oder WPF-Anwendung):

  1. Starten Sie Ihre App bis
  2. Zugriff Wert in app.config
  3. Eine Änderung an app.config
  4. überprüfen Sie, ob der neue Wert ConfigurationManager.RefreshSection("appSettings")
  5. überprüfen Sie, ob der neue Wert vorhanden
  6. Call ist zu sehen, ist anwesend.

In der Tat, ich selbst könnte einige Zeit gespeichert, wenn ich nur den Kommentar auf der RefreshSection Methode :-)

/// <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> 
1
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; 

Alle zeigen den gleichen Lastaccesstime, die im Cache gespeichert es bedeutet gelesen habe am Anfang.

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

     DateTime fourth = file.LastAccessTime; 
7

Die einfache Antwort ist nein, es liest es nicht immer aus der Datei. Wie einige vorgeschlagen haben, wenn die Datei geändert wird, führt IIS einen Neustart aber nicht immer aus! Wenn Sie sicherstellen wollen, dass Sie den neuesten Wert aus der Datei und nicht aus dem Cache Sie so etwas nennen müssen lesen:

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

Und ein Beispiel, das ich in meinem Code verwenden:

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

Damit können Sie sehr einfach auswählen (und beim Lesen von Code), ob Sie jedes Mal den letzten Wert erhalten oder ob Sie erwarten, dass sich der Wert nicht ändert, wenn die Anwendung gestartet wird.

+1

was meinst du mit "nicht immer"! das ist von Entwurf Ich habe verstanden, dass IIS die App neu startet und die Konfiguration neu lädt. –

Verwandte Themen