RKP
RKP

Reputation: 5385

getting an exception when refreshing the configuration in memory on change to external config file

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]));                
    }
}

Upvotes: 0

Views: 1665

Answers (2)

RKP
RKP

Reputation: 5385

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);
    }

}

Upvotes: 0

Jacob
Jacob

Reputation: 78890

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.

Upvotes: 1

Related Questions