无需重启应用程序即可更改应用程序配置

6
我有以下问题:我正在将新功能引入应用程序(作为Windows服务运行),我希望使用某种配置文件条目(myKey)来控制新功能的开启和关闭。我可以将配置条目存储在app.config中,但如果我想从开启到关闭或者反过来进行更改,那么就需要重新启动Windows服务,而我想避免这种情况。我希望我的应用程序能够运行并且能够获取配置文件的更改。
问题是:.NET是否有内置机制来解决这个问题?我猜我可以创建自己的配置文件,然后使用FileSystemWatcher等等...但也许.NET允许使用外部配置文件并重新加载值?
ConfigurationManager.AppSettings["myKey"]

谢谢,Pawel

编辑1:感谢回复。然而我写了以下代码片段,但它不起作用(我尝试在循环之前和循环内部创建appSettingSection):

static void Main(string[] args)
{
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    // AppSettingsSection appSettingSection = (AppSettingsSection)config.GetSection("appSettings");
    for (int i = 0; i < 10; i++)
    {
        ConfigurationManager.RefreshSection("appSettings");
        AppSettingsSection appSettingSection = (AppSettingsSection)config.GetSection("appSettings");
        string myConfigData = appSettingSection.Settings["myConfigData"].Value; // still the same value, doesn't get updated
        Console.WriteLine();
        Console.WriteLine("Using GetSection(string).");
        Console.WriteLine("AppSettings section:");
        Console.WriteLine(
          appSettingSection.SectionInformation.GetRawXml()); // also XML is still the same
        Console.ReadLine();
    }
}

当应用程序停止在Console.ReadLine()时,我会手动编辑配置文件。

3个回答

6

一旦原始的app.config文件被加载,它的值就会被缓存,所以你需要重新启动应用程序。解决这个问题的方法是创建一个新的配置对象并手动读取键值,例如:

var appConfig = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
string myConfigData = appConfig.AppSettings.Settings["myConfigData"].Value;

谢谢!但是,这样每次访问myConfigData时,我都需要创建一个新的配置对象,以确保appConfig.AppSettings.Settings["myConfigData"].Value与app.config文件中的底层值一致吗? - dragonfly
11
在调用 appConfig.AppSettings.Settings["myConfigData"].Value; 之前,只需调用 ConfigurationManager.RefreshSection("appSettings"); 即可强制应用程序读取新的和已更改的设置。否则,ConfigurationManager 会默认缓存所有值。请注意不要改变原文的意思。 - Teoman Soygul
1
@TeomanSoygul RefreshSection调用会更新通过ConfigurationManager.AppSettings[]检索到的值,但不会影响配置实例。 - SerG

1
如果您手动处理配置(可能甚至不在app.config文件中),那么您可以定期检查该文件是否有更新。 FileSystemWatcher可能有点过头了,并且并不适用于所有情况。个人而言,我会每隔30秒轮询一次该文件。

你好,你是指使用@Teoman Soygul描述的解决方案进行池化吗?我认为每1分钟重新加载该设置就可以满足我的需求了。 - dragonfly
@dragonfly 嗯,有点像;虽然我不一定会使用 app-config 路径。任何路由都可以,这并不需要很复杂。 - Marc Gravell

0

在读取值之前,只需从当前配置文件刷新“appSettings”:

ConfigurationManager.RefreshSection("appSettings"); // Reload app settings from config file
ConfigurationManager.AppSettings["myKey"];          // Read the value as usually

不需要通过创建另一个配置或在您的问题或其他答案中建议的任何配置来使它过于复杂化!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接