protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
            {
                _contextAccessor = await _workspaceProjectContextProvider.CreateProjectContextAsync(_project);

                if (_contextAccessor == null)
                {
                    return;
                }

                _activeWorkspaceProjectContextTracker.RegisterContext(_contextAccessor.ContextId);

                _disposables = new DisposableBag(CancellationToken.None);

                _applyChangesToWorkspaceContext = _applyChangesToWorkspaceContextFactory.CreateExport();
                _applyChangesToWorkspaceContext.Value.Initialize(_contextAccessor.Context);
                _disposables.AddDisposable(_applyChangesToWorkspaceContext);

                _evaluationProgressRegistration = _dataProgressTrackerService.RegisterForIntelliSense(_project, nameof(WorkspaceProjectContextHostInstance) + ".Evaluation");
                _disposables.AddDisposable(_evaluationProgressRegistration);

                _projectBuildProgressRegistration = _dataProgressTrackerService.RegisterForIntelliSense(_project, nameof(WorkspaceProjectContextHostInstance) + ".ProjectBuild");
                _disposables.AddDisposable(_projectBuildProgressRegistration);

                // We avoid suppressing version updates, so that progress tracker doesn't
                // think we're still "in progress" in the case of an empty change
                _disposables.AddDisposable(_projectSubscriptionService.ProjectRuleSource.SourceBlock.LinkToAsyncAction(
                                               target: e => OnProjectChangedAsync(e, evaluation: true),
                                               suppressVersionOnlyUpdates: false,
                                               ruleNames: _applyChangesToWorkspaceContext.Value.GetProjectEvaluationRules()));

                _disposables.AddDisposable(_projectSubscriptionService.ProjectBuildRuleSource.SourceBlock.LinkToAsyncAction(
                                               target: e => OnProjectChangedAsync(e, evaluation: false),
                                               suppressVersionOnlyUpdates: false,
                                               ruleNames: _applyChangesToWorkspaceContext.Value.GetProjectBuildRules()));
            }
Ejemplo n.º 2
0
            internal Task OnProjectChangedAsync <T>(
                IDataProgressTrackerServiceRegistration registration,
                ConfiguredProject activeConfiguredProject,
                IProjectVersionedValue <T> update,
                Func <IProjectVersionedValue <T>, bool> hasChange,
                Action <IProjectVersionedValue <T>, IApplyChangesToWorkspaceContext, ContextState, CancellationToken> applyFunc)
            {
                return(ExecuteUnderLockAsync(ApplyProjectChangesUnderLockAsync, _tasksService.UnloadCancellationToken));

                Task ApplyProjectChangesUnderLockAsync(CancellationToken cancellationToken)
                {
                    // NOTE we cannot call CheckForInitialized here, as this method may be invoked during initialization
                    Assumes.NotNull(_contextAccessor);
                    Assumes.NotNull(_applyChangesToWorkspaceContext);

                    if (!hasChange(update))
                    {
                        // No change since the last update. We must still update operation progress, but can skip creating a batch.
                        UpdateProgressRegistration();
                        return(Task.CompletedTask);
                    }

                    return(ApplyInBatchAsync());

                    async Task ApplyInBatchAsync()
                    {
                        ContextState contextState = new(
                            isActiveEditorContext : _activeWorkspaceProjectContextTracker.IsActiveEditorContext(_contextAccessor.ContextId),
                            isActiveConfiguration : activeConfiguredProject == _project);

                        IWorkspaceProjectContext context = _contextAccessor.Context;

                        context.StartBatch();

                        try
                        {
                            applyFunc(update, _applyChangesToWorkspaceContext.Value, contextState, cancellationToken);
                        }
                        finally
                        {
                            await context.EndBatchAsync();

                            UpdateProgressRegistration();
                        }
                    }

                    void UpdateProgressRegistration()
                    {
                        // Notify operation progress that we've now processed these versions of our input, if they are
                        // up-to-date with the latest version that produced, then we no longer considered "in progress".
                        registration.NotifyOutputDataCalculated(update.DataSourceVersions);
                    }
                }
            }