internal void OnSolutionBuildCompleted() { // building is done. reset the state // and get local copy of in-progress state var inProgressState = ClearInProgressState(); // enqueue build/live sync in the queue. var asyncToken = _listener.BeginAsyncOperation("OnSolutionBuild"); _taskQueue.ScheduleTask(async() => { // nothing to do if (inProgressState == null) { return; } _lastBuiltResult = inProgressState.GetBuildDiagnostics(); // we are about to update live analyzer data using one from build. // pause live analyzer using (var operation = _notificationService.Start("BuildDone")) { if (_diagnosticService is DiagnosticAnalyzerService diagnosticService) { await CleanupAllLiveErrorsAsync(diagnosticService, inProgressState.GetProjectsWithoutErrors()).ConfigureAwait(false); await SyncBuildErrorsAndReportAsync(diagnosticService, inProgressState).ConfigureAwait(false); } inProgressState.Done(); } }).CompletesAsyncOperation(asyncToken); }
internal void OnSolutionBuildCompleted() { // building is done. reset the state // and get local copy of in-progress state var inProgressState = ClearInProgressState(); // enqueue build/live sync in the queue. _taskQueue.ScheduleTask("OnSolutionBuild", async() => { // nothing to do if (inProgressState == null) { return; } // explicitly start solution crawler if it didn't start yet. since solution crawler is lazy, // user might have built solution before workspace fires its first event yet (which is when solution crawler is initialized) // here we give initializeLazily: false so that solution crawler is fully initialized when we do de-dup live and build errors, // otherwise, we will think none of error we have here belong to live errors since diagnostic service is not initialized yet. var registrationService = (SolutionCrawlerRegistrationService)_workspace.Services.GetService <ISolutionCrawlerRegistrationService>(); registrationService.EnsureRegistration(_workspace, initializeLazily: false); _lastBuiltResult = inProgressState.GetBuildDiagnostics(); // we are about to update live analyzer data using one from build. // pause live analyzer using var operation = _notificationService.Start("BuildDone"); if (_diagnosticService is DiagnosticAnalyzerService diagnosticService) { await CleanupAllLiveErrorsAsync(diagnosticService, inProgressState.GetProjectsWithoutErrors()).ConfigureAwait(false); await SyncBuildErrorsAndReportAsync(diagnosticService, inProgressState).ConfigureAwait(false); } inProgressState.Done(); }, CancellationToken.None);
private void TrackBulkFileOperations() { RoslynDebug.AssertNotNull(_workspace); // we will pause whatever ambient work loads we have that are tied to IGlobalOperationNotificationService // such as solution crawler, pre-emptive remote host synchronization and etc. any background work users didn't // explicitly asked for. // // this should give all resources to BulkFileOperation. we do same for things like build, // debugging, wait dialog and etc. BulkFileOperation is used for things like git branch switching and etc. IGlobalOperationNotificationService globalNotificationService = _workspace.Services.GetRequiredService <IGlobalOperationNotificationService>(); // BulkFileOperation can't have nested events. there will be ever only 1 events (Begin/End) // so we only need simple tracking. object gate = new object(); GlobalOperationRegistration?localRegistration = null; BulkFileOperation.End += (s, a) => { StopBulkFileOperationNotification(); }; BulkFileOperation.Begin += (s, a) => { StartBulkFileOperationNotification(); }; void StartBulkFileOperationNotification() { lock (gate) { // this shouldn't happen, but we are using external component // so guarding us from them if (localRegistration != null) { FatalError.ReportWithoutCrash(new InvalidOperationException("BulkFileOperation already exist")); return; } localRegistration = globalNotificationService.Start("BulkFileOperation"); } } void StopBulkFileOperationNotification() { lock (gate) { // this can happen if BulkFileOperation was already in the middle // of running. to make things simpler, decide to not use IsInProgress // which we need to worry about race case. if (localRegistration == null) { return; } localRegistration.Dispose(); localRegistration = null; } } }
private void ContextChanged(bool active, string operation) { if (_notificationService == null) { return; } TryCancelPendingNotification(operation); if (active) { _operations[operation] = _notificationService.Start(operation); } }
public VisualStudioWaitContext( IGlobalOperationNotificationService notificationService, IVsThreadedWaitDialogFactory dialogFactory, string title, string message, bool allowCancel) { _title = title; _message = message; _allowCancel = allowCancel; _cancellationTokenSource = new CancellationTokenSource(); _dialog = CreateDialog(dialogFactory); _registration = notificationService.Start(title); }
public VisualStudioWaitContext( IGlobalOperationNotificationService notificationService, IVsThreadedWaitDialogFactory dialogFactory, string title, string message, bool allowCancel, bool showProgress) { _title = title; _message = message; _allowCancel = allowCancel; _cancellationTokenSource = new CancellationTokenSource(); this.ProgressTracker = showProgress ? new ProgressTracker((_1, _2) => UpdateDialog()) : new ProgressTracker(); _dialog = CreateDialog(dialogFactory, showProgress); _registration = notificationService.Start(title); }
public VisualStudioWaitContext( IGlobalOperationNotificationService notificationService, IVsThreadedWaitDialogFactory dialogFactory, string title, string message, bool allowCancel, bool showProgress) { _title = title; _message = message; _allowCancel = allowCancel; _cancellationTokenSource = new CancellationTokenSource(); this.ProgressTracker = showProgress ? new ProgressTracker((_1, _2, _3) => UpdateDialog()) : new ProgressTracker(); _dialog = CreateDialog(dialogFactory, showProgress); _registration = notificationService.Start(title); }
internal void OnSolutionBuildCompleted() { // Building is done, so reset the state // and get local copy of in-progress state. var inProgressState = ClearInProgressState(); // Enqueue build/live sync in the queue. _taskQueue.ScheduleTask("OnSolutionBuild", async() => { // nothing to do if (inProgressState == null) { return; } // Explicitly start solution crawler if it didn't start yet. since solution crawler is lazy, // user might have built solution before workspace fires its first event yet (which is when solution crawler is initialized) // here we give initializeLazily: false so that solution crawler is fully initialized when we do de-dup live and build errors, // otherwise, we will think none of error we have here belong to live errors since diagnostic service is not initialized yet. var registrationService = (SolutionCrawlerRegistrationService)_workspace.Services.GetRequiredService <ISolutionCrawlerRegistrationService>(); registrationService.EnsureRegistration(_workspace, initializeLazily: false); // Mark the status as updated to refresh error list before we invoke 'SyncBuildErrorsAndReportAsync', which can take some time to complete. OnBuildProgressChanged(inProgressState, BuildProgress.Updated); // We are about to update live analyzer data using one from build. // pause live analyzer using var operation = _notificationService.Start("BuildDone"); if (_diagnosticService is DiagnosticAnalyzerService diagnosticService) { await SyncBuildErrorsAndReportOnBuildCompletedAsync(diagnosticService, inProgressState).ConfigureAwait(false); } // Mark build as complete. OnBuildProgressChanged(inProgressState, BuildProgress.Done); }, CancellationToken.None);