internal async Task OnProjectChangedAsync_WhenProjectUnloaded_TriggersCancellation(WorkspaceContextHandlerType handlerType) { var unloadSource = new CancellationTokenSource(); var tasksService = IUnconfiguredProjectTasksServiceFactory.ImplementUnloadCancellationToken(unloadSource.Token); void ApplyProjectBuild(IProjectVersionedValue <IProjectSubscriptionUpdate> _, IProjectBuildSnapshot projectBuildSnapshot, ContextState __, CancellationToken cancellationToken) { // Unload project unloadSource.Cancel(); cancellationToken.ThrowIfCancellationRequested(); } void ApplyProjectEvaluation(IProjectVersionedValue <IProjectSubscriptionUpdate> _, ContextState __, CancellationToken cancellationToken) { // Unload project unloadSource.Cancel(); cancellationToken.ThrowIfCancellationRequested(); } var applyChangesToWorkspaceContext = handlerType switch { WorkspaceContextHandlerType.Evaluation => IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectEvaluationAsync(ApplyProjectEvaluation), WorkspaceContextHandlerType.ProjectBuild => IApplyChangesToWorkspaceContextFactory.ImplementApplyProjectBuildAsync(ApplyProjectBuild), WorkspaceContextHandlerType.SourceItems => IApplyChangesToWorkspaceContextFactory.ImplementApplySourceItemsAsync(ApplyProjectEvaluation), // ApplyProjectEvaluation works for source items as they share a signature _ => throw new NotImplementedException() }; var instance = await CreateInitializedInstanceAsync(tasksService : tasksService, applyChangesToWorkspaceContext : applyChangesToWorkspaceContext); var update = IProjectVersionedValueFactory.Create <(ConfiguredProject, IProjectSubscriptionUpdate, IProjectBuildSnapshot)>((default !, default !, Mock.Of <IProjectBuildSnapshot>()));
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); } }
private void NotifyOutputDataCalculated(IImmutableDictionary <NamedIdentity, IComparable> dataSourceVersions, WorkspaceContextHandlerType handlerType) { // 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". switch (handlerType) { case WorkspaceContextHandlerType.Evaluation: _evaluationProgressRegistration !.NotifyOutputDataCalculated(dataSourceVersions); break; case WorkspaceContextHandlerType.ProjectBuild: _projectBuildProgressRegistration !.NotifyOutputDataCalculated(dataSourceVersions); break; case WorkspaceContextHandlerType.SourceItems: _sourceItemsProgressRegistration !.NotifyOutputDataCalculated(dataSourceVersions); break; } }
internal Task OnProjectChangedAsync(ProjectChange change, WorkspaceContextHandlerType handlerType) { return(ExecuteUnderLockAsync(ct => ApplyProjectChangesUnderLockAsync(change, handlerType, ct), _tasksService.UnloadCancellationToken)); }