Index: XmlConfigurator.cs
===================================================================
--- XmlConfigurator.cs (revision 607768)
+++ XmlConfigurator.cs (working copy)
@@ -870,9 +870,23 @@
try
{
- // Create a watch handler that will reload the
- // configuration whenever the config file is modified.
- ConfigureAndWatchHandler.StartWatching(repository, configFile);
+ lock (m_repositoryName2ConfigAndWatchHandler)
+ {
+ // support multiple repositories each having their own watcher
+ ConfigureAndWatchHandler handler =
+ (ConfigureAndWatchHandler)m_repositoryName2ConfigAndWatchHandler[repository.Name];
+
+ if (handler != null)
+ {
+ m_repositoryName2ConfigAndWatchHandler.Remove(repository.Name);
+ handler.Dispose();
+ }
+
+ // Create and start a watch handler that will reload the
+ // configuration whenever the config file is modified.
+ handler = new ConfigureAndWatchHandler(repository, configFile);
+ m_repositoryName2ConfigAndWatchHandler[repository.Name] = handler;
+ }
}
catch(Exception ex)
{
@@ -903,24 +917,9 @@
/// elapse.
///
///
- private sealed class ConfigureAndWatchHandler
+ private sealed class ConfigureAndWatchHandler : IDisposable
{
///
- /// Watch a specified config file used to configure a repository
- ///
- /// The repository to configure.
- /// The configuration file to watch.
- ///
- ///
- /// Watch a specified config file used to configure a repository
- ///
- ///
- internal static void StartWatching(ILoggerRepository repository, FileInfo configFile)
- {
- new ConfigureAndWatchHandler(repository, configFile);
- }
-
- ///
/// Holds the FileInfo used to configure the XmlConfigurator
///
private FileInfo m_configFile;
@@ -941,8 +940,15 @@
///
private const int TimeoutMillis = 500;
+ ///
+ /// Watches file for changes. This object should be disposed when no longer
+ /// needed to free system handles on the watched resources.
+ ///
+ private FileSystemWatcher m_watcher;
+
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class to
+ /// watch a specified config file used to configure a repository.
///
/// The repository to configure.
/// The configuration file to watch.
@@ -951,31 +957,31 @@
/// Initializes a new instance of the class.
///
///
- private ConfigureAndWatchHandler(ILoggerRepository repository, FileInfo configFile)
+ public ConfigureAndWatchHandler(ILoggerRepository repository, FileInfo configFile)
{
m_repository = repository;
m_configFile = configFile;
// Create a new FileSystemWatcher and set its properties.
- FileSystemWatcher watcher = new FileSystemWatcher();
+ m_watcher = new FileSystemWatcher();
- watcher.Path = m_configFile.DirectoryName;
- watcher.Filter = m_configFile.Name;
+ m_watcher.Path = m_configFile.DirectoryName;
+ m_watcher.Filter = m_configFile.Name;
// Set the notification filters
- watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName;
+ m_watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName;
// Add event handlers. OnChanged will do for all event handlers that fire a FileSystemEventArgs
- watcher.Changed += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
- watcher.Created += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
- watcher.Deleted += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
- watcher.Renamed += new RenamedEventHandler(ConfigureAndWatchHandler_OnRenamed);
+ m_watcher.Changed += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
+ m_watcher.Created += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
+ m_watcher.Deleted += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
+ m_watcher.Renamed += new RenamedEventHandler(ConfigureAndWatchHandler_OnRenamed);
// Begin watching.
- watcher.EnableRaisingEvents = true;
+ m_watcher.EnableRaisingEvents = true;
// Create the timer that will be used to deliver events. Set as disabled
- m_timer = new Timer(new TimerCallback(OnWatchedFileChange), null, Timeout.Infinite, Timeout.Infinite);
+ m_timer = new Timer(new TimerCallback(OnWatchedFileChange), null, Timeout.Infinite, Timeout.Infinite);
}
///
@@ -1019,11 +1025,21 @@
///
/// Called by the timer when the configuration has been updated.
///
- /// null
+ /// null
private void OnWatchedFileChange(object state)
{
XmlConfigurator.InternalConfigure(m_repository, m_configFile);
}
+
+ ///
+ /// Release the handles held by the watcher and timer.
+ ///
+ public void Dispose()
+ {
+ m_watcher.EnableRaisingEvents = false;
+ m_watcher.Dispose();
+ m_timer.Dispose();
+ }
}
#endif
@@ -1083,6 +1099,13 @@
#region Private Static Fields
+ ///
+ /// Maps repository names to ConfigAndWatchHandler instances to allow a particular
+ /// ConfigAndWatchHandler to dispose of its FileSystemWatcher when a repository is
+ /// reconfigured.
+ ///
+ private readonly static Hashtable m_repositoryName2ConfigAndWatchHandler = new Hashtable();
+
///
/// The fully qualified type of the XmlConfigurator class.
///