2012-11-13 18 views
64

मैं बस सोच रहा हूं कि ConfigurationManager.AppSettings [कुंजी] कैसे काम करता है?क्या ConfigurationManager.AppSettings [Key] प्रत्येक बार web.config फ़ाइल से पढ़ता है?

क्या हर बार जब मुझे कुंजी की आवश्यकता होती है तो क्या यह भौतिक फ़ाइल से पढ़ता है?

यदि हां, तो क्या मुझे अपने web.config की सभी ऐप सेटिंग्स को कैश में पढ़ना चाहिए और फिर इसे पढ़ना चाहिए?

या एएसपी.नेट या आईआईएस web.config फ़ाइल को application_startup पर लोड करता है और केवल एक बार।

यह सत्यापित करने के लिए कि प्रत्येक फ़ाइल द्वारा भौतिक फ़ाइल का उपयोग कैसे किया जाता है?

यदि मैं web.config बदलता हूं, तो आईआईएस मेरे एप्लिकेशन को पुनरारंभ करता है, इसलिए इसे इस तरह से सत्यापित नहीं किया जा सकता है।

धन्यवाद,

उत्तर

78

यह कैश की गई हो जाता है, एक संपत्ति के पहले उपयोग पर, तो यह भौतिक फ़ाइल से हर बार जब आप एक मूल्य के लिए पूछना नहीं पढ़ता। यही कारण है कि नवीनतम मान प्राप्त करने के लिए Windows एप (या Refresh कॉन्फ़िगरेशन) को पुनरारंभ करना आवश्यक है, और जब आप web.config संपादित करते हैं तो ASP.Net ऐप स्वचालित रूप से पुनरारंभ क्यों होता है। How to prevent an ASP.NET application restarting when the web.config is modified उत्तर में संदर्भों में पुनरारंभ करने के लिए 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; 
    } 
} 

सबसे पहले, यह वास्तव में दिखता है जैसे कि यह अनुभाग हर बार मिल जाएगा। GetSection को देखते हुए:

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

यहां महत्वपूर्ण लाइन PrepareConfigSystem() विधि है; यह कॉन्फ़िगरेशन मैनेजर द्वारा आयोजित IInternalConfigSystem फ़ील्ड का एक उदाहरण शुरू करता है - कंक्रीट प्रकार ClientConfigurationSystem

इस लोड के हिस्से के रूप में, Configuration कक्षा का एक उदाहरण तत्काल है। यह वर्ग प्रभावी रूप से कॉन्फ़िगरेशन फ़ाइल का एक ऑब्जेक्ट प्रस्तुति है, और यह क्लाइंट कॉन्फ़िगरेशन सिस्टम द्वारा क्लाइंट कॉन्फ़िगरेशनहोस्ट संपत्ति द्वारा स्थिर क्षेत्र में आयोजित किया जाता है - इसलिए यह कैश किया गया है।

आप ऐसा करके अनुभव इस परीक्षण कर सकते हैं निम्नलिखित (एक 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> 
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; 

सभी एक ही LastAccessTime जिसका अर्थ यह कैश की गई है दिखाने प्रारंभ होने पर।

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

     DateTime fourth = file.LastAccessTime; 
7

सरल उत्तर नहीं है, यह हमेशा फ़ाइल से इसे नहीं पढ़ता है। जैसा कि कुछ ने सुझाव दिया है कि फ़ाइल बदल दी गई है, तो आईआईएस पुनरारंभ करता है लेकिन हमेशा नहीं!

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

आपका मतलब "हमेशा नहीं" से क्या मतलब है! यह डिज़ाइन द्वारा मैंने समझा है कि आईआईएस ऐप को पुनरारंभ करता है और कॉन्फ़िगर को फिर से लोड करता है। –

संबंधित मुद्दे