Example #1
0
        private async Task CreateLibraryWatchers()
        {
            Debug.Assert(_libWatchers != null, "Should not create watchers when suppressed");

            IReadOnlyList <string> paths = null;

            if (_factory.Configuration.SearchPaths.Any())
            {
                paths = _factory.Configuration.SearchPaths;
            }

            if (paths == null)
            {
                try {
                    paths = (await PythonLibraryPath.GetSearchPathsAsync(_factory.Configuration, new FileSystem(new OSPlatform()), new ProcessServices()))
                            .Select(p => p.Path)
                            .ToArray();
                } catch (InvalidOperationException) {
                    return;
                }
            }

            paths = paths
                    .Where(Directory.Exists)
                    .OrderBy(p => p.Length)
                    .ToList();

            var watching = new List <string>();
            var watchers = new List <FileSystemWatcher>();

            foreach (var path in paths)
            {
                if (watching.Any(p => PathUtils.IsSubpathOf(p, path)))
                {
                    continue;
                }

                FileSystemWatcher watcher = null;
                try {
                    watcher = new FileSystemWatcher {
                        IncludeSubdirectories = true,
                        Path         = path,
                        NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite
                    };
                    watcher.Created            += OnChanged;
                    watcher.Deleted            += OnChanged;
                    watcher.Changed            += OnChanged;
                    watcher.Renamed            += OnRenamed;
                    watcher.EnableRaisingEvents = true;

                    watching.Add(path);
                    watchers.Add(watcher);
                } catch (IOException) {
                    // Raced with directory deletion. We normally handle the
                    // library being deleted by disposing the watcher, but this
                    // occurs in response to an event from the watcher. Because
                    // we never got to start watching, we will just dispose
                    // immediately.
                    watcher?.Dispose();
                } catch (ArgumentException ex) {
                    watcher?.Dispose();
                    Debug.WriteLine("Error starting FileSystemWatcher:\r\n{0}", ex);
                }
            }

            List <FileSystemWatcher> oldWatchers;

            lock (_libWatchers) {
                oldWatchers = _libWatchers.ToList();
                _libWatchers.Clear();
                _libWatchers.AddRange(watchers);
            }

            foreach (var oldWatcher in oldWatchers)
            {
                oldWatcher.EnableRaisingEvents = false;
                oldWatcher.Dispose();
            }
        }