2017-03-02 69 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

我明白你的意思了!对不起,有点慢!我会给它当很多人说你可以在网上做这件事时,令人沮丧,让我觉得有一些简单,但显然是错误的,我试图。立场,将更新它的方式! –