private void SquashAndLogChanges(FileSystemEventBatchArgs args) { var list = new List <SimpleFileChangedEventArgs>(); foreach (var arg in args.FileEvents) { var simpleArg = new SimpleFileChangedEventArgs(arg); var index = list.IndexOf(simpleArg); if (index >= 0) { list.RemoveAt(index); } list.Add(simpleArg); } args.FileEvents.Clear(); foreach (var change in list) { var e = change.Args; if (!IsPathToWatch(e.FullPath)) { continue; } args.FileEvents.Add(e); if (Site.CanInfo()) { Site.Info($"File event occured: {e.ChangeType} -> {e.FullPath}"); } } }
private void ProcessEvents() { _threadStarted = true; while (true) { FileSystemEventBatchArgs batchEventsCopy = null; if (_onClosingEvent.WaitOne(SleepForward)) { break; } lock (_batchLock) { if (_clock.ElapsedMilliseconds <= MillisTimeout) { continue; } if (_batchEvents != null && _batchEvents.FileEvents.Count > 0) { batchEventsCopy = _batchEvents; _batchEvents = null; } else { continue; } } // TODO: squash events here (to avoid having duplicated events) // Invoke listeners try { SquashAndLogChanges(batchEventsCopy); // Squash can discard events (e.g if files excluded) if (batchEventsCopy.FileEvents.Count > 0) { FileSystemEvents?.Invoke(this, batchEventsCopy); } } catch (Exception ex) { Site.Error(ex, $"Unexpected error on SiteWatcher callback. Reason: {ex.GetReason()}"); } } _onClosingEvent.Reset(); }
private void OnFileSystemEvent(object sender, FileChangedEventArgs e) { // Don't log events until the thread is started if (!_threadStarted) { return; } var dir = new DirectoryEntry(e.FileSystem, e.FullPath); if (IsOutputDirectory(e.FullPath)) { return; } lock (_watchers) { var isDirectory = dir.Exists; switch (e.ChangeType) { case WatcherChangeTypes.Deleted: if (isDirectory) { DisposeWatcher(dir); } break; case WatcherChangeTypes.Created: // Create watcher only for top-level directories if (isDirectory && dir.Parent != null && dir.Parent == _siteDirectory) { WatchFolder(dir); } break; case WatcherChangeTypes.Renamed: var renamed = (FileRenamedEventArgs)e; if (isDirectory) { var previousDirectory = new DirectoryEntry(renamed.FileSystem, renamed.OldFullPath); if (_watchers.TryGetValue(previousDirectory, out _)) { DisposeWatcher(previousDirectory); // Create watcher only for top-level directories if (dir.Parent != null && dir.Parent == _siteDirectory) { WatchFolder(dir); } } } break; } } lock (_batchLock) { _clock.Restart(); if (_batchEvents == null) { _batchEvents = new FileSystemEventBatchArgs(); } _batchEvents.FileEvents.Add(e); } }