Ejemplo n.º 1
0
        public VisualStudioFileChangeTrackerFactory(
            ForegroundDispatcher foregroundDispatcher,
            ErrorReporter errorReporter,
            IVsAsyncFileChangeEx fileChangeService,
            JoinableTaskContext joinableTaskContext)
        {
            if (foregroundDispatcher == null)
            {
                throw new ArgumentNullException(nameof(foregroundDispatcher));
            }

            if (errorReporter == null)
            {
                throw new ArgumentNullException(nameof(errorReporter));
            }

            if (fileChangeService == null)
            {
                throw new ArgumentNullException(nameof(fileChangeService));
            }

            if (joinableTaskContext is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskContext));
            }

            _foregroundDispatcher = foregroundDispatcher;
            _errorReporter        = errorReporter;
            _joinableTaskContext  = joinableTaskContext;
            _fileChangeService    = fileChangeService;
        }
        public VisualStudioFileChangeTrackerFactory(
            ErrorReporter errorReporter,
            IVsAsyncFileChangeEx fileChangeService,
            ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
            JoinableTaskContext joinableTaskContext)
        {
            if (errorReporter is null)
            {
                throw new ArgumentNullException(nameof(errorReporter));
            }

            if (fileChangeService is null)
            {
                throw new ArgumentNullException(nameof(fileChangeService));
            }

            if (projectSnapshotManagerDispatcher is null)
            {
                throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
            }

            if (joinableTaskContext is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskContext));
            }

            _errorReporter     = errorReporter;
            _fileChangeService = fileChangeService;
            _projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
            _joinableTaskContext = joinableTaskContext;
        }
        public VisualStudioFileChangeTracker(
            string filePath,
            ForegroundDispatcher foregroundDispatcher,
            ErrorReporter errorReporter,
            IVsAsyncFileChangeEx fileChangeService,
            JoinableTaskFactory joinableTaskFactory)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(filePath));
            }

            if (foregroundDispatcher == null)
            {
                throw new ArgumentNullException(nameof(foregroundDispatcher));
            }

            if (errorReporter == null)
            {
                throw new ArgumentNullException(nameof(errorReporter));
            }

            if (fileChangeService == null)
            {
                throw new ArgumentNullException(nameof(fileChangeService));
            }

            FilePath = filePath;
            _foregroundDispatcher = foregroundDispatcher;
            _errorReporter        = errorReporter;
            _fileChangeService    = fileChangeService;
            _joinableTaskFactory  = joinableTaskFactory ?? throw new ArgumentNullException();
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Completing the output block before the action block means any final messages that are currently being produced
                // will not be sent out, which is what we want in this case.
                _broadcastBlock?.Complete();
                _dataSourceLink?.Dispose();

                if (_actionBlock != null)
                {
                    _actionBlock.Complete();

                    _threadingService.ExecuteSynchronously(async() =>
                    {
                        // Wait for any processing to finish so we don't fight over the cookies 🍪
                        await _actionBlock.Completion;

                        IVsAsyncFileChangeEx vsAsyncFileChangeEx = await _fileChangeService.GetValueAsync();

                        // Unsubscribe from all files
                        foreach (uint cookie in _fileWatcherCookies.Values)
                        {
                            await vsAsyncFileChangeEx.UnadviseFileChangeAsync(cookie);
                        }
                    });
                }
            }

            base.Dispose(disposing);
        }
        private async Task UnregisterFileWatcherIfAnyAsync()
        {
            // Note file change service is free-threaded
            if (_filechangeCookie != VSConstants.VSCOOKIE_NIL)
            {
                IVsAsyncFileChangeEx fileChangeService = await _fileChangeService.GetValueAsync();

                // There's nothing for us to do if this fails. So ignore the return value.
                await fileChangeService.UnadviseFileChangeAsync(_filechangeCookie);

                _watchedFileResetCancellationToken?.Cancel();
                _watchedFileResetCancellationToken?.Dispose();
                _taskDelayScheduler?.Dispose();
            }
        }
        private async Task ProcessDesignTimeInputs(IProjectVersionedValue <DesignTimeInputs> input)
        {
            DesignTimeInputs designTimeInputs = input.Value;

            IVsAsyncFileChangeEx vsAsyncFileChangeEx = await _fileChangeService.GetValueAsync();

            // we don't care about the difference between types of inputs, so we just construct one hashset for fast comparisons later
            var allFiles = new HashSet <string>(StringComparers.Paths);

            allFiles.AddRange(designTimeInputs.Inputs);
            allFiles.AddRange(designTimeInputs.SharedInputs);

            // Remove any files we're watching that we don't care about any more
            var removedFiles = new List <string>();

            foreach ((string file, uint cookie) in _fileWatcherCookies)
            {
                if (!allFiles.Contains(file))
                {
                    await vsAsyncFileChangeEx.UnadviseFileChangeAsync(cookie);

                    removedFiles.Add(file);
                }
            }

            foreach (string file in removedFiles)
            {
                _fileWatcherCookies.Remove(file);
            }

            // Now watch and output files that are new
            foreach (string file in allFiles)
            {
                if (!_fileWatcherCookies.ContainsKey(file))
                {
                    // We don't care about delete and add here, as they come through data flow, plus they are really bouncy - every file change is a Time, Del and Add event)
                    uint cookie = await vsAsyncFileChangeEx.AdviseFileChangeAsync(file, _VSFILECHANGEFLAGS.VSFILECHG_Time | _VSFILECHANGEFLAGS.VSFILECHG_Size, sink : this);

                    _fileWatcherCookies.Add(file, cookie);
                }
            }
        }
Ejemplo n.º 7
0
        public VisualStudioFileChangeTrackerFactoryFactory(ForegroundDispatcher foregroundDispatcher, SVsServiceProvider serviceProvider, JoinableTaskContext joinableTaskContext)
        {
            if (foregroundDispatcher == null)
            {
                throw new ArgumentNullException(nameof(foregroundDispatcher));
            }

            if (serviceProvider == null)
            {
                throw new ArgumentNullException(nameof(serviceProvider));
            }

            if (joinableTaskContext is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskContext));
            }

            _foregroundDispatcher = foregroundDispatcher;
            _joinableTaskContext  = joinableTaskContext;
            _fileChangeService    = serviceProvider.GetService(typeof(SVsFileChangeEx)) as IVsAsyncFileChangeEx;
        }
        private async Task RegisterFileWatcherAsync(string projectLockJsonFilePath)
        {
            // Note file change service is free-threaded
            if (projectLockJsonFilePath != null)
            {
                _previousContentsHash = GetFileHashOrNull(projectLockJsonFilePath);
                _taskDelayScheduler?.Dispose();
                _taskDelayScheduler = new TaskDelayScheduler(
                    s_notifyDelay,
                    _projectServices.ThreadingService,
                    CreateLinkedCancellationToken());

                IVsAsyncFileChangeEx fileChangeService = await _fileChangeService.GetValueAsync();

                _filechangeCookie = await fileChangeService.AdviseFileChangeAsync(
                    projectLockJsonFilePath,
                    _VSFILECHANGEFLAGS.VSFILECHG_Time | _VSFILECHANGEFLAGS.VSFILECHG_Size | _VSFILECHANGEFLAGS.VSFILECHG_Add | _VSFILECHANGEFLAGS.VSFILECHG_Del,
                    sink : this);
            }

            _fileBeingWatched = projectLockJsonFilePath;
        }
Ejemplo n.º 9
0
        public VisualStudioFileChangeTracker(
            string filePath,
            ErrorReporter errorReporter,
            IVsAsyncFileChangeEx fileChangeService,
            ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
            JoinableTaskContext joinableTaskContext)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(filePath));
            }

            if (errorReporter is null)
            {
                throw new ArgumentNullException(nameof(errorReporter));
            }

            if (fileChangeService is null)
            {
                throw new ArgumentNullException(nameof(fileChangeService));
            }

            if (projectSnapshotManagerDispatcher is null)
            {
                throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
            }

            if (joinableTaskContext is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskContext));
            }

            FilePath           = filePath;
            _errorReporter     = errorReporter;
            _fileChangeService = fileChangeService;
            _projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
            _joinableTaskContext = joinableTaskContext;
        }
        private static DesignTimeInputsFileWatcher CreateDesignTimeInputsFileWatcher(IVsAsyncFileChangeEx fileChangeService, out ProjectValueDataSource <DesignTimeInputs> source)
        {
            // Create our mock design time inputs data source, but with a source we can actually use
            var services = IProjectCommonServicesFactory.CreateWithDefaultThreadingPolicy();

            source = ProjectValueDataSourceFactory.Create <DesignTimeInputs>(services);

            var mock = new Mock <IDesignTimeInputsDataSource>();

            mock.SetupGet(s => s.SourceBlock)
            .Returns(source.SourceBlock);

            var dataSource = mock.Object;

            var threadingService            = IProjectThreadingServiceFactory.Create();
            var unconfiguredProject         = UnconfiguredProjectFactory.Create(fullPath: @"C:\MyProject\MyProject.csproj");
            var unconfiguredProjectServices = IUnconfiguredProjectServicesFactory.Create(
                projectService: IProjectServiceFactory.Create(
                    services: ProjectServicesFactory.Create(
                        threadingService: threadingService)));

            // Create our class under test
            return(new DesignTimeInputsFileWatcher(unconfiguredProject, unconfiguredProjectServices, threadingService, dataSource, IVsServiceFactory.Create <SVsFileChangeEx, IVsAsyncFileChangeEx>(fileChangeService)));
        }
Ejemplo n.º 11
0
        public VisualStudioFileChangeTrackerFactoryFactory(
            SVsServiceProvider serviceProvider,
            ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
            JoinableTaskContext joinableTaskContext)
        {
            if (serviceProvider is null)
            {
                throw new ArgumentNullException(nameof(serviceProvider));
            }

            if (projectSnapshotManagerDispatcher is null)
            {
                throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
            }

            if (joinableTaskContext is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskContext));
            }

            _fileChangeService = serviceProvider.GetService(typeof(SVsFileChangeEx)) as IVsAsyncFileChangeEx;
            _projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
            _joinableTaskContext = joinableTaskContext;
        }