app.config 刷新部分未重新加载应用程序设置部分
app.config refresh section not reloading the appsettings section
好吧,我讨厌这个 "not working" 上有很多其他帖子,但鉴于我花了 3 天时间试图让 ConfigurationManager 在运行时重新加载以防止重新启动我的服务,我无处可去转.
我一直在使用这篇博客文章:
http://dejanstojanovic.net/aspnet/2015/june/auto-realod-application-config-in-net/
帮助我创建一个 filewatcher,然后在保存文件时重新加载该部分。
我修改了它以刷新有关文件更改的 appSettings 部分(请参见下面的代码);但是,无论我尝试哪种方式,它都不会刷新该部分,只会显示启动时的值。
我试过:
- 将监视器 class 从外部项目移到同一个 codebase/project 以确保它不会作为某种跨域保护业务受到干扰。
- 在 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;
}
}
您可以尝试加载配置的新实例,而不是使用静态 ConfigurationManager。
var appSettings = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetEntryAssembly().Location).AppSettings;
string setting = appSettings.Settings[strKeyName].Value;
好吧,我讨厌这个 "not working" 上有很多其他帖子,但鉴于我花了 3 天时间试图让 ConfigurationManager 在运行时重新加载以防止重新启动我的服务,我无处可去转.
我一直在使用这篇博客文章:
http://dejanstojanovic.net/aspnet/2015/june/auto-realod-application-config-in-net/
帮助我创建一个 filewatcher,然后在保存文件时重新加载该部分。
我修改了它以刷新有关文件更改的 appSettings 部分(请参见下面的代码);但是,无论我尝试哪种方式,它都不会刷新该部分,只会显示启动时的值。
我试过:
- 将监视器 class 从外部项目移到同一个 codebase/project 以确保它不会作为某种跨域保护业务受到干扰。
- 在 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;
}
}
您可以尝试加载配置的新实例,而不是使用静态 ConfigurationManager。
var appSettings = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetEntryAssembly().Location).AppSettings;
string setting = appSettings.Settings[strKeyName].Value;