2012-11-13 26 views
64

私は、ConfigurationManager.AppSettings [Key]がどのように機能するのか不思議です。ConfigurationManager.AppSettings [Key]は毎回web.configファイルから読み込みますか?

鍵が必要なたびに物理ファイルから読み込みますか?

もしそうなら、キャッシュ内のweb.configのすべてのアプリ設定を読み込んでから読み込む必要がありますか?

または、ASP.NETまたはIISは、web_configファイルをapplication_startupで1回だけ読み込みます。

読み込みごとに物理ファイルにアクセスするかどうかを確認する方法は?

web.configを変更した場合、IISはアプリケーションを再起動しますので、そのように確認することはできません。

おかげで、

答えて

78

それは物理的なファイルからあなたが値を求めるたびに読み込まれませんので、それは、プロパティの最初のアクセスで、キャッシュされます。このため、最新の値を取得するためにはWindowsアプリケーション(またはRefresh)を再起動する必要があり、web.configを編集するとASP.Netアプリケーションが自動的に再起動するのはなぜですか。 ASP.Netがなぜ再起動するように配線されているのかは、回答How to prevent an ASP.NET application restarting when the web.config is modifiedの参考文献で説明されています。

我々は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; 
    } 
} 

最初はそれがセクションごとに時間を取得するように、これは確かに見えません。 GetSectionを見て:

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

ここで重要なラインがPrepareConfigSystem()方法です。これは、構成管理によって保持IInternalConfigSystemフィールドのインスタンスを初期化 - 具象型はConfigurationクラスのインスタンスがインスタンス化され、この負荷の一部としてClientConfigurationSystem

あります。このクラスは実質的にconfigファイルのオブジェクト表現であり、静的フィールドのClientConfigurationSystemのClientConfigurationHostプロパティによって保持されているように見えるため、キャッシュされます。

あなたが行うことによって、経験的に、これをテストすることができ(WindowsフォームやWPFアプリで)次

  1. がに変更を加えます
  2. アクセスアップのapp.config
  3. の値を、あなたのアプリケーションの起動新しい値が新しい値かどうかを確認することが、本
  4. コールConfigurationManager.RefreshSection("appSettings")
  5. チェックされているかどうかをapp.configを
  6. チェック存在する。実際に

私はちょうど

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

すべて:-) RefreshSection方法にコメントを読んだ場合、私は自分自身にいくつかの時間を保存している可能性があり、それがキャッシュされた意味と同じLastAccessTimeを表示起動時に

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

     DateTime fourth = file.LastAccessTime; 
7

単純な答えはいいえ、必ずしもファイルから読み取られるわけではありません。ファイルが変更された場合には、IISが再起動を実行するが、必ずしもそうではないと示唆している人もいます。

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

そして、私は私のコードで使用例:

/// ====================================================================================== 
/// <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; 
} 
あなたはファイルではなく、キャッシュから非常に最新の値を読んでいることを保証したい場合には、このような何かを呼び出す必要があります

これにより、毎回最新の値を取得しているかどうか、またはアプリケーションの起動時に値が変更されることを期待しないかどうかを非常に簡単に選択できます。

+1

「いつもではない」とはどういう意味ですか?それは設計上、私はIISがアプリケーションを再起動し、設定を再ロードすることを理解しています。 –

関連する問題