static void UpdateWatchers(CancellationToken token) { if (token.IsCancellationRequested) { return; } lock (watchers) { if (token.IsCancellationRequested) { return; } newWatchers.Clear(); foreach (var node in tree.Normalize(maxWatchers)) { if (token.IsCancellationRequested) { return; } var dir = node.GetPath().ToString(); if (Directory.Exists(dir)) { newWatchers.Add(dir); } } if (newWatchers.Count == 0 && watchers.Count == 0) { // Unchanged. return; } toRemove.Clear(); foreach (var kvp in watchers) { var directory = kvp.Key; if (!newWatchers.Contains(directory)) { toRemove.Add(directory); } } // After this point, the watcher update is real and a destructive operation, so do not use the token. if (token.IsCancellationRequested) { return; } // First remove the watchers, so we don't spin too many threads. foreach (var directory in toRemove) { RemoveWatcher_NoLock(directory); } // Add the new ones. foreach (var path in newWatchers) { // Don't modify a watcher that already exists. if (watchers.ContainsKey(path)) { continue; } var watcher = new FileWatcherWrapper(path); watchers.Add(path, watcher); try { watcher.EnableRaisingEvents = true; } catch (UnauthorizedAccessException e) { LoggingService.LogWarning("Access to " + path + " denied. Stopping file watcher.", e); watcher.Dispose(); watchers.Remove(path); } } } }
static void UpdateWatchers( List <WorkspaceItem> currentWorkspaceItems, Dictionary <object, List <FilePath> > currentMonitoredDirectories, CancellationToken token) { List <FileWatcherWrapper> newWatchers = null; HashSet <FilePath> watchedDirectories = GetWatchedDirectories(); if (token.IsCancellationRequested) { return; } foreach (FilePath directory in GetRootDirectories(currentWorkspaceItems, currentMonitoredDirectories)) { if (!watchedDirectories.Remove(directory)) { if (Directory.Exists(directory)) { if (newWatchers == null) { newWatchers = new List <FileWatcherWrapper> (); } var watcher = new FileWatcherWrapper(directory); newWatchers.Add(watcher); } } } if (newWatchers == null && !watchedDirectories.Any()) { // Unchanged. return; } lock (watchers) { if (token.IsCancellationRequested) { if (newWatchers != null) { foreach (FileWatcherWrapper watcher in newWatchers) { watcher.Dispose(); } } return; } // Remove file watchers no longer needed. foreach (FilePath directory in watchedDirectories) { Remove(directory); } if (newWatchers != null) { foreach (FileWatcherWrapper watcher in newWatchers) { watchers.Add(watcher.Path, watcher); watcher.EnableRaisingEvents = true; } } } }
static void UpdateWatchers(CancellationToken token) { if (token.IsCancellationRequested) { return; } lock (watchers) { if (token.IsCancellationRequested) { return; } var newPathsToWatch = tree.Normalize(maxWatchers).Select(node => (FilePath)node.FullPath); var newWatchers = new HashSet <FilePath> (newPathsToWatch.Where(dir => Directory.Exists(dir))); if (newWatchers.Count == 0 && watchers.Count == 0) { // Unchanged. return; } List <FilePath> toRemove; if (newWatchers.Count == 0) { toRemove = watchers.Keys.ToList(); } else { toRemove = new List <FilePath> (); foreach (var kvp in watchers) { var directory = kvp.Key; if (!newWatchers.Contains(directory)) { toRemove.Add(directory); } } } // After this point, the watcher update is real and a destructive operation, so do not use the token. if (token.IsCancellationRequested) { return; } // First remove the watchers, so we don't spin too many threads. foreach (var directory in toRemove) { RemoveWatcher_NoLock(directory); } // Add the new ones. if (newWatchers.Count == 0) { return; } foreach (var path in newWatchers) { // Don't modify a watcher that already exists. if (watchers.ContainsKey(path)) { continue; } var watcher = new FileWatcherWrapper(path); watchers.Add(path, watcher); watcher.EnableRaisingEvents = true; } } }