/// <summary> /// Called when one of the project files changes. In our case since only one file is watched with each cookie so the list of files /// should be one. /// </summary> public int FilesChanged(uint cChanges, string[] rgpszFile, uint[] grfChange) { if (cChanges == 1 && (grfChange[0] & (uint)(_VSFILECHANGEFLAGS.VSFILECHG_Size | _VSFILECHANGEFLAGS.VSFILECHG_Time)) != 0) { IReloadableProject changedProject = null; lock (_registeredProjects) { changedProject = _registeredProjects.FirstOrDefault(kv => kv.Key.ProjectFile.Equals(rgpszFile[0], StringComparison.OrdinalIgnoreCase)).Key; } if (changedProject != null) { lock (_changedProjects) { if (!_changedProjects.Contains(changedProject)) { _changedProjects.Add(changedProject); } ReloadDelayScheduler.ScheduleAsyncTask(async(ct) => { // Grab the UI thread so that we block until the reload of this set of // projects completes. await _threadHandling.SwitchToUIThread(); if (ct.IsCancellationRequested) { return; } // Get the list of projects and create a new empty list to put new requests List <IReloadableProject> changedProjects; lock (_changedProjects) { changedProjects = _changedProjects; _changedProjects = new List <IReloadableProject>(); } var failedProjects = new List <Tuple <IReloadableProject, ProjectReloadResult> >(); _threadHandling.ExecuteSynchronously(async() => { foreach (var project in changedProjects) { ProjectReloadResult result = await project.ReloadProjectAsync().ConfigureAwait(true); if (result == ProjectReloadResult.ReloadFailed || result == ProjectReloadResult.ReloadFailedProjectDirty) { failedProjects.Add(new Tuple <IReloadableProject, ProjectReloadResult>(project, result)); } } }); ProcessProjectReloadFailures(failedProjects); }); } } } return(VSConstants.S_OK); }
/// <summary> /// IDisposable handler. Should only be called once /// </summary> protected override async Task DisposeCoreAsync(bool initialized) { if (ReloadDelayScheduler != null) { ReloadDelayScheduler.Dispose(); ReloadDelayScheduler = null; } await DisconnectFromSolutionEvents().ConfigureAwait(false); }