void UpdateFileSystemWatchers() { _indUnloadSignal.OnGet(); // update watchers when something is unloaded // - We only need watchers when Options.AutoUnload (TODO: when AutoUnload // changes, unload/reload assemblies) // - We only want to watch folders that contain unloaded assemblies. To // approximate this, look for assemblies that have no tasks (these // may actually still be loaded by other assemblies, but that's ok) if (Options.AutoUnload) { var activeAssemblies = new Dictionary <string, object>(); foreach (var task in _runner.QueuedAndRunningTasks().OfType <ITaskEx>()) { activeAssemblies[task.AssemblyPath] = null; } var inactiveAssemblies = _assemblies.Where(a => !activeAssemblies.ContainsKey(a.Path)); var inactivePaths = new Dictionary <string, FileSystemWatcher>(); foreach (var a in inactiveAssemblies) { inactivePaths[Path.GetFullPath(Path.Combine(a.Path, ".."))] = null; } // inactivePaths contains the set of paths to watch. // Add/remove watchers in _watchers to synchronize with that set. var removes = new List <FileSystemWatcher>(); foreach (var watcher in _watchers) { if (!inactivePaths.ContainsKey(watcher.Path)) { removes.Add(watcher); } else { inactivePaths[watcher.Path] = watcher; } } RemoveWatchers(removes); foreach (var pair in inactivePaths.Where(pair => pair.Value == null)) { Trace.WriteLine("Starting to watch " + pair.Key); var watcher = new FileSystemWatcher(pair.Key); watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; FileSystemEventHandler OnChanged = (s, e) => { foreach (var a in _assemblies) { if (string.Compare(a.Path, e.FullPath, true) == 0) { a.UpdatePending = true; } } }; watcher.Changed += OnChanged; watcher.Created += OnChanged; watcher.Renamed += new RenamedEventHandler(OnChanged); _watchers.Add(watcher); } } else { RemoveWatchers(_watchers); } }