2017-03-02 75 views
0

好吧,我討厭在這個「不工作」上有其他帖子的負載,但考慮到我花了3天的時間嘗試讓ConfigurationManager在運行時重新加載以防止重新啓動我的服務,我無處可轉。app.config刷新部分不重新載入appsettings部分

我一直用這個博客文章:

http://dejanstojanovic.net/aspnet/2015/june/auto-realod-application-config-in-net/

幫助我創造一個filewatcher那然後重新加載,當文件被保存的部分。

我修改了它來刷新文件更改的appSettings部分(請參閱下面的代碼);然而,無論我嘗試哪種方式,它都不會刷新該部分,只會在啓動時顯示值。

我曾嘗試:

  • 從外部項目移動顯示器類,在同一個代碼庫/項目,以確保它不是被幹擾的某種跨域保護業務。
  • 將一個單獨的部分添加到app.config中並重新加載,以確保它不會基於保護appSettings部分的某些.net安全性。
  • 重命名appSettings每一種方式我都可以確保它不是一個命名問題(無處不讀refreshsection(..)區分大小寫)。

希望有人在這裏可以指出我在哪裏這樣一個白癡!

代碼:

public class ConfigMonitor 
{ 
    private readonly FileSystemWatcher _watcher; 
    private DateTime _lastChange; 

    public ConfigMonitor(string configFilePath) 
    { 
     if (configFilePath == null) 
     { 
      throw new ArgumentNullException(nameof(configFilePath)); 
     } 

     _lastChange = DateTime.MinValue; 
     configFilePath = string.Concat(System.Reflection.Assembly.GetEntryAssembly().Location, ".config"); 
     if (File.Exists(configFilePath)) 
     { 
      _watcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath)) 
      { 
       EnableRaisingEvents = true 
      }; 
      _watcher.Changed += Watcher_Changed; 
     } 
    } 

    ~ConfigMonitor() 
    { 
     _watcher.EnableRaisingEvents = false; 
     _watcher.Changed -= Watcher_Changed; 
     _watcher.Dispose(); 
    } 

    public void Stop() 
    { 
     _watcher.EnableRaisingEvents = false; 
     _watcher.Changed -= Watcher_Changed; 
     _watcher.Dispose(); 
    } 

    private void Watcher_Changed(object sender, FileSystemEventArgs e) 
    { 
     if ((DateTime.Now - _lastChange).Seconds <= 5 || IsFileLocked(e.FullPath)) return; 
     var monitoredSections = ConfigurationManager.AppSettings["monitoredSections"]; 

     if (monitoredSections != null) 
     { 
      IEnumerable<string> sections = monitoredSections.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); 
      if (sections.Any()) 
      { 
       foreach (var section in sections) 
       { 
        ConfigurationManager.RefreshSection(section); 
       } 
      } 
     } 
     else 
     { 
      Debug.WriteLine(ConfigurationManager.AppSettings["TEST"]); 
      ConfigurationManager.RefreshSection("appSettings"); 
      Debug.WriteLine(ConfigurationManager.AppSettings["TEST"]); 
     } 
     _lastChange = DateTime.Now; 
    } 

    private bool IsFileLocked(string filePath) 
    { 
     FileStream stream = null; 
     try 
     { 
      stream = File.OpenRead(filePath); 
     } 
     catch (IOException) 
     { 
      return true; 
     } 
     finally 
     { 
      stream?.Close(); 
     } 
     return false; 
    } 
} 
+0

是否執行過任何'Debug.WriteLine'測試? – caesay

+0

@caesay,yeh'writelines'出來了,只是打印出相同的值(它是在啓動時加載的/在啓動時加載的 –

回答

0

而不是使用靜態ConfigurationManager中,你可以嘗試加載配置的新實例。

var appSettings = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetEntryAssembly().Location).AppSettings; 
string setting = appSettings.Settings[strKeyName].Value; 
+0

在運行時執行了這個工作嗎?我被引導認爲你不能重新加載配置管理器它指向別的地方)後,你已經調用/訪問配置中的屬性(我一直在尋找重定位到一個單獨的文件夾,以防止通過一個繁忙的dll文件夾搜索) –

+0

所以你應該有一個包裝類,說一個靜態的'Settings'類,私人存儲這個配置管理器的一個實例,當你想重新加載配置時,只需用新的配置替換實例 – caesay

+0

我明白你的意思了!對不起,有點慢!我會給它當很多人說你可以在網上做這件事時,令人沮喪,讓我覺得有一些簡單,但顯然是錯誤的,我試圖。立場,將更新它的方式! –