在更改外部配置文件时刷新内存中的配置时出现异常

发布于 2024-10-08 19:48:16 字数 892 浏览 0 评论 0原文

我有一个 Windows 服务,它从外部文件读取配置设置,该文件位于与 Windows 服务的可执行文件路径不同的路径中。 Windows 服务使用 FileSystemWatcher 来监视外部配置文件的更改,当配置文件更改时,它应该通过从配置文件中读取更新的设置来刷新内存中的设置。但这就是我收到异常“ConfigurationErrorsException”的地方,消息是“为 appSettings 创建配置节处理程序时发生错误:该进程无法访问文件“M:\somefolder\WindowsService1.Config”,因为它正在被使用另一个过程。”内部异常实际上是具有相同消息的“IOException”。这是代码。我不确定代码有什么问题。请帮忙。

protected void watcher_Changed(object sender, FileSystemEventArgs e)
{
    ConfigurationManager.RefreshSection(ConfigSectionName);
    WriteToEventLog(ConfigKeyCheck);

    if (FileChanged != null)
        FileChanged(this, EventArgs.Empty);
}

private void WriteToEventLog(string key)
{
    if (EventLog.SourceExists(ServiceEventSource))
    {
        EventLog.WriteEntry(ServiceEventSource,
                            string.Format("key:{0}, value:{1}", key, ConfigurationManager.AppSettings[key]));                
    }
}

I have a windows service which reads the config settings from an external file which is located at a different path than the path to the executable for the windows service. the windows service uses a FileSystemWatcher to monitor the changes to the external config file and when it the config file is changed, it should refresh the settings in memory by reading the updated settings from the config file. but this is where I am getting an exception "ConfigurationErrorsException" and the message is "An error occurred creating the configuration section handler for appSettings: The process cannot access the file 'M:\somefolder\WindowsService1.Config' because it is being used by another process." and the inner exception is actually "IOException" with same message. here is the code. I am not sure what is wrong with the code. Please help.

protected void watcher_Changed(object sender, FileSystemEventArgs e)
{
    ConfigurationManager.RefreshSection(ConfigSectionName);
    WriteToEventLog(ConfigKeyCheck);

    if (FileChanged != null)
        FileChanged(this, EventArgs.Empty);
}

private void WriteToEventLog(string key)
{
    if (EventLog.SourceExists(ServiceEventSource))
    {
        EventLog.WriteEntry(ServiceEventSource,
                            string.Format("key:{0}, value:{1}", key, ConfigurationManager.AppSettings[key]));                
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦亿 2024-10-15 19:48:16

如果在每次检测到更改时尝试重新读取配置部分,您应该预料到会发生 IO 异常。例如,文件可能被锁定(如您的情况),或者写入可能仅部分完成。您应该将代码放在 try/catch 块中,捕获 IOException(也许更多),然后稍后重试刷新,也许计时器过去后。

You should expect that IO exceptions occur if trying to re-read the configuration section upon every detected change. For example, the file could be locked (as in your case), or write could be only partially completed. You should just put the code in a try/catch block, catch IOExceptions (and maybe more), and retry the refresh later, perhaps after a timer elapses.

怀中猫帐中妖 2024-10-15 19:48:16

根据雅各布的建议更改了代码,现在它可以工作了(我尝试仅捕获 IOException,但它不起作用)。如果异常发生超过 3 次,则异常将被吞掉,但任何后续从配置文件中的读取都将抛出未处理的异常,迫使服务停止。希望这种情况不会发生。

private void WriteToEventLog(string key)
{
    try
    {
        if (EventLog.SourceExists(ServiceEventSource))
        {
            EventLog.WriteEntry(ServiceEventSource,
                                string.Format("key:{0}, value:{1}", key, ConfigurationManager.AppSettings[key]));
            _configReadCount = 0;
        }
    }
    catch (Exception)
    {
        System.Threading.Thread.Sleep(TimeSpan.FromMinutes(1)); //sleep for a minute and try again
        _configReadCount++;
        if (_configReadCount <= 3) //try 3 times 
            WriteToEventLog(ConfigKeyCheck);
    }

}

changed the code as per Jacob's suggestion and it works now (I tried catching only IOException, but it didn't work). if exception occurs more than 3 times, then the exception is swallowed, but any subsequent reads from config file will throw unhandled exception forcing the service to stop. hopefully that situation won't occur.

private void WriteToEventLog(string key)
{
    try
    {
        if (EventLog.SourceExists(ServiceEventSource))
        {
            EventLog.WriteEntry(ServiceEventSource,
                                string.Format("key:{0}, value:{1}", key, ConfigurationManager.AppSettings[key]));
            _configReadCount = 0;
        }
    }
    catch (Exception)
    {
        System.Threading.Thread.Sleep(TimeSpan.FromMinutes(1)); //sleep for a minute and try again
        _configReadCount++;
        if (_configReadCount <= 3) //try 3 times 
            WriteToEventLog(ConfigKeyCheck);
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文