Пример #1
0
        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);
        }
Пример #2
0
        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);
Пример #3
0
        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;
                }
            }
        }
Пример #4
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);