private void RaiseEventForChange([NotNull] FakeFileSystemVersionedChange change) { string rootDirectory = change.RootDirectory.GetText(); switch (change.ChangeType) { case WatcherChangeTypes.Created: { Created?.Invoke(this, new FileSystemEventArgs(change.ChangeType, rootDirectory, change.RelativePath)); break; } case WatcherChangeTypes.Deleted: { Deleted?.Invoke(this, new FileSystemEventArgs(change.ChangeType, rootDirectory, change.RelativePath)); break; } case WatcherChangeTypes.Changed: { Changed?.Invoke(this, new FileSystemEventArgs(change.ChangeType, rootDirectory, change.RelativePath)); break; } case WatcherChangeTypes.Renamed: { Renamed?.Invoke(this, new RenamedEventArgs(change.ChangeType, rootDirectory, change.RelativePath, change.PreviousRelativePathInRename)); break; } } }
private void ConsumeNextVersionedChange([NotNull] FakeFileSystemVersionedChange change) { bool doRaiseBufferOverflowEvent = false; bool doRaiseChangeEvent = false; lock (lockObject) { if (hasBufferOverflow && !consumerIsFlushingBuffer) { doRaiseBufferOverflowEvent = true; consumerIsFlushingBuffer = true; } if (change.Version == version) { doRaiseChangeEvent = true; } } try { if (change.IsDeleteOfWatcherDirectory) { RaiseEventForWatcherDirectoryDeleted(); EnableRaisingEvents = false; } else { if (doRaiseBufferOverflowEvent) { RaiseEventForBufferOverflow(); } if (doRaiseChangeEvent) { RaiseEventForChange(change); } } } finally { // When an event handler throws, the process terminates (because of unhandled exception on background thread) by default. // This can be overruled with <legacyUnhandledExceptionPolicy enabled="1" /> in app.config, in which case we'll be broken. // Because after the first uncaught exception, this loop terminates and we no longer raise subsequent events. // Such scenario is so rare though, that we ignore the problem for now. lock (lockObject) { if (!producerConsumerQueue.Any()) { hasBufferOverflow = false; consumerIsFlushingBuffer = false; } } } }