예제 #1
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);
                    }
                }
            }
        private async Task <IWorkspaceProjectContext?> CreateProjectContextHandlingFaultAsync(ProjectContextInitData data, object?hostObject)
        {
            try
            {
                // Call into Roslyn to init language service for this project
                IWorkspaceProjectContext context = await _workspaceProjectContextFactory.Value.CreateProjectContextAsync(
                    data.LanguageName,
                    data.WorkspaceProjectContextId,
                    data.ProjectFilePath,
                    data.ProjectGuid,
                    hostObject,
                    data.BinOutputPath,
                    data.AssemblyName,
                    CancellationToken.None);

                context.StartBatch();

                try
                {
                    // Update additional properties within a batch to avoid thread pool starvation.
                    // https://github.com/dotnet/project-system/issues/8027

                    context.LastDesignTimeBuildSucceeded = false;  // By default, turn off diagnostics until the first design time build succeeds for this project.

                    // Pass along any early approximation we have of the command line options
#pragma warning disable CS0618 // This was obsoleted in favor of the one that takes an array, but here just the string is easier; we'll un-Obsolete this API
                    context.SetOptions(data.CommandLineArgsForDesignTimeEvaluation);
#pragma warning restore CS0618 // Type or member is obsolete
                }
                finally
                {
                    await context.EndBatchAsync();
                }

                return(context);
            }
            catch (Exception ex)
            {
                await _faultHandlerService.ReportFaultAsync(ex, _project, ProjectFaultSeverity.LimitedFunctionality);
            }

            return(null);
        }
            private async Task ApplyProjectChangesUnderLockAsync(ProjectChange change, WorkspaceContextHandlerType handlerType, CancellationToken cancellationToken)
            {
                // NOTE we cannot call CheckForInitialized here, as this method may be invoked during initialization
                Assumes.NotNull(_contextAccessor);

                IWorkspaceProjectContext context = _contextAccessor.Context;
                bool isActiveEditorContext       = _activeWorkspaceProjectContextTracker.IsActiveEditorContext(_contextAccessor.ContextId);
                bool isActiveConfiguration       = change.Project == _project;

                var state = new ContextState(isActiveEditorContext, isActiveConfiguration);

                context.StartBatch();

                try
                {
                    switch (handlerType)
                    {
                    case WorkspaceContextHandlerType.Evaluation:
                        await _applyChangesToWorkspaceContext !.Value.ApplyProjectEvaluationAsync(change.Subscription, state, cancellationToken);
                        break;

                    case WorkspaceContextHandlerType.ProjectBuild:
                        Assumes.NotNull(change.BuildSnapshot);
                        await _applyChangesToWorkspaceContext !.Value.ApplyProjectBuildAsync(change.Subscription, change.BuildSnapshot, state, cancellationToken);
                        break;

                    case WorkspaceContextHandlerType.SourceItems:
                        await _applyChangesToWorkspaceContext !.Value.ApplySourceItemsAsync(change.Subscription, state, cancellationToken);
                        break;
                    }
                }
                finally
                {
                    await context.EndBatchAsync();

                    NotifyOutputDataCalculated(change.DataSourceVersions, handlerType);
                }
            }