예제 #1
0
        private void AddDirectory(FullPath directory)
        {
            DirectoryWatcherhEntry watcherEntry;

            lock (_watchersLock) {
                if (_pollingThread == null)
                {
                    _pollingThread = new Thread(ThreadLoop)
                    {
                        IsBackground = true
                    };
                    _pollingThread.Start();
                }
                if (_watchers.TryGetValue(directory, out watcherEntry))
                {
                    return;
                }

                watcherEntry = new DirectoryWatcherhEntry {
                    Path = directory,
                    DirectoryNameWatcher = _fileSystem.CreateDirectoryWatcher(directory),
                    FileNameWatcher      = _fileSystem.CreateDirectoryWatcher(directory),
                    FileWriteWatcher     = _fileSystem.CreateDirectoryWatcher(directory),
                };
                _watchers.Add(directory, watcherEntry);
            }

            Logger.LogInfo("Starting monitoring directory \"{0}\" for change notifications.", directory);

            // Note: "DirectoryName" captures directory creation, deletion and rename
            watcherEntry.DirectoryNameWatcher.NotifyFilter = NotifyFilters.DirectoryName;
            watcherEntry.DirectoryNameWatcher.Changed     += (s, e) => WatcherOnChanged(s, e, PathKind.Directory);
            watcherEntry.DirectoryNameWatcher.Created     += (s, e) => WatcherOnCreated(s, e, PathKind.Directory);
            watcherEntry.DirectoryNameWatcher.Deleted     += (s, e) => WatcherOnDeleted(s, e, PathKind.Directory);
            watcherEntry.DirectoryNameWatcher.Renamed     += (s, e) => WatcherOnRenamed(s, e, PathKind.Directory);

            // Note: "FileName" captures file creation, deletion and rename
            watcherEntry.FileNameWatcher.NotifyFilter = NotifyFilters.FileName;
            watcherEntry.FileNameWatcher.Changed     += (s, e) => WatcherOnChanged(s, e, PathKind.File);
            watcherEntry.FileNameWatcher.Created     += (s, e) => WatcherOnCreated(s, e, PathKind.File);
            watcherEntry.FileNameWatcher.Deleted     += (s, e) => WatcherOnDeleted(s, e, PathKind.File);
            watcherEntry.FileNameWatcher.Renamed     += (s, e) => WatcherOnRenamed(s, e, PathKind.File);

            // Note: "LastWrite" will catch changes to *both* files and directories, i.e. it is
            // not possible to known which one it is.
            // For directories, a "LastWrite" change occurs when a child entry (file or directory) is added,
            // renamed or deleted.
            // For files, a "LastWrite" change occurs when the file is written to.
            watcherEntry.FileWriteWatcher.NotifyFilter = NotifyFilters.LastWrite;
            watcherEntry.FileWriteWatcher.Changed     += (s, e) => WatcherOnChanged(s, e, PathKind.FileOrDirectory);
            watcherEntry.FileWriteWatcher.Created     += (s, e) => WatcherOnCreated(s, e, PathKind.FileOrDirectory);
            watcherEntry.FileWriteWatcher.Deleted     += (s, e) => WatcherOnDeleted(s, e, PathKind.FileOrDirectory);
            watcherEntry.FileWriteWatcher.Renamed     += (s, e) => WatcherOnRenamed(s, e, PathKind.FileOrDirectory);

            foreach (var watcher in new[]
                     { watcherEntry.DirectoryNameWatcher, watcherEntry.FileNameWatcher, watcherEntry.FileWriteWatcher })
            {
                watcher.IncludeSubdirectories = true;
                // Note: The MSDN documentation says to use less than 64KB
                //       (see https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.internalbuffersize(v=vs.110).aspx)
                //         "You can set the buffer to 4 KB or larger, but it must not exceed 64 KB."
                //       However, the implementation allows for arbitrary buffer sizes.
                //       Experience has shown that 64KB is small enough that we frequently run into "OverflowException"
                //       exceptions on heavily active file systems (e.g. during a build of a complex project
                //       such as Chromium).
                //       The issue with these exceptions is that the consumer must be extremely conservative
                //       when such errors occur, because we lost track of what happened at the individual
                //       directory/file level. In the case of VsChromium, the server will batch a full re-scan
                //       of the file system, instead of an incremental re-scan, and that can be quite time
                //       consuming (as well as I/O consuming).
                //       In the end, increasing the size of the buffer to 2 MB is the best option to avoid
                //       these issues (2 MB is not that much memory in the grand scheme of things).
                watcher.InternalBufferSize = 2 * 1024 * 1024; // 2 MB
                watcher.Error += WatcherOnError;
                watcher.Start();
            }
        }
예제 #2
0
 public abstract State OnWatcherRemoved(FullPath directory, DirectoryWatcherhEntry watcher);
 public override State OnWatcherRemoved(FullPath directory, DirectoryWatcherhEntry watcher)
 {
     return(BackToState());
 }
 public override State OnWatcherAdded(FullPath directory, DirectoryWatcherhEntry watcher)
 {
     return(this);
 }