【问题标题】:getting an exception when refreshing the configuration in memory on change to external config file在更改外部配置文件时刷新内存中的配置时出现异常
【发布时间】:2011-05-29 00:24:12
【问题描述】:

我有一个 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]));                
    }
}

【问题讨论】:

  • 配置文件如何变化?用户正在编辑文件还是应用程序正在更新文件?如果用户正在编辑它,他们可以使用像 notepad++ 这样的非锁定编辑器,如果应用程序正在编辑它,它也应该尽量避免锁定文件。无论如何,我的回答应该可以帮助您处理文件锁定问题。
  • 由用户而非应用程序编辑。我使用 Visual Studio 更新配置文件(应用程序仍在开发中)。

标签: c# configuration windows-services app-config


【解决方案1】:

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

【讨论】:

  • 现在可以使用了,谢谢。不确定 ASP.NET 如何为 web.config 文件处理此问题,因为这些设置会自动刷新,无需编写任何代码,也不会引发任何锁定异常,不确定是否也使用计时器。
【解决方案2】:

按照 Jacob 的建议更改了代码,现在可以正常工作了(我尝试只捕获 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);
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-07
    • 2011-12-07
    • 1970-01-01
    • 2018-03-17
    • 2014-05-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多