src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/LanguageServices/LanguageServiceHost.cs
/// <summary>
/// Ensures that <see cref="_currentAggregateProjectContext"/> is updated for the latest target frameworks from the project properties
/// and returns this value.
/// </summary>
Ensures that  is updated for the latest target frameworks from the project properties
and returns this value.
Ensures that is updated for the latest target frameworks from the project properties and returns this value .
private async Task<AggregateWorkspaceProjectContext> UpdateProjectContextAsync()
        {
            AggregateWorkspaceProjectContext previousContextToDispose = null;
            return await ExecuteWithinLockAsync(async () =>
            {
                await _commonServices.ThreadingService.SwitchToUIThread();
                string newTargetFramework = null;
                var projectProperties = await _commonServices.ActiveConfiguredProjectProperties.GetConfigurationGeneralPropertiesAsync().ConfigureAwait(false);
                if (_currentAggregateProjectContext != null)
                {
                    if (!_currentAggregateProjectContext.IsCrossTargeting)
                    {
                        newTargetFramework = (string)await projectProperties.TargetFramework.GetValueAsync().ConfigureAwait(false);
                        if (StringComparers.PropertyValues.Equals(_currentTargetFramework, newTargetFramework))
                        {
                            return _currentAggregateProjectContext;
                        }
                        await DisposeAggregateProjectContextAsync(_currentAggregateProjectContext).ConfigureAwait(false);
                    }
                    else
                    {
                        var activeProjectConfiguration = _commonServices.ActiveConfiguredProject.ProjectConfiguration;
                        var knownProjectConfigurations = await _commonServices.Project.Services.ProjectConfigurationsService.GetKnownProjectConfigurationsAsync().ConfigureAwait(false);
                        if (knownProjectConfigurations.All(c => c.IsCrossTargeting()) &&
                            _currentAggregateProjectContext.HasMatchingTargetFrameworks(activeProjectConfiguration, knownProjectConfigurations))
                        {
                            return _currentAggregateProjectContext;
                        }
                        previousContextToDispose = _currentAggregateProjectContext;
                    }
                }
                else
                {
                    newTargetFramework = (string)await projectProperties.TargetFramework.GetValueAsync().ConfigureAwait(false);
                }
                await _commonServices.ThreadingService.SwitchToUIThread();
                await _activeProjectConfigurationRefreshService.RefreshActiveProjectConfigurationAsync().ConfigureAwait(false);
                _currentAggregateProjectContext = await _contextProvider.Value.CreateProjectContextAsync().ConfigureAwait(false);
                _currentTargetFramework = newTargetFramework;
                if (previousContextToDispose != null)
                {
                    await DisposeAggregateProjectContextAsync(previousContextToDispose).ConfigureAwait(false);
                }
                return _currentAggregateProjectContext;
            }).ConfigureAwait(false);
        }
private async Task < AggregateWorkspaceProjectContext > UpdateProjectContextAsync ( ) { AggregateWorkspaceProjectContext previousContextToDispose = null ; return await ExecuteWithinLockAsync ( async ( ) => { await _commonServices . ThreadingService . SwitchToUIThread ( ) ; string newTargetFramework = null ; var projectProperties = await _commonServices . ActiveConfiguredProjectProperties . GetConfigurationGeneralPropertiesAsync ( ) . ConfigureAwait ( false ) ; if ( _currentAggregateProjectContext != null ) { if ( ! _currentAggregateProjectContext . IsCrossTargeting ) { newTargetFramework = ( string ) await projectProperties . TargetFramework . GetValueAsync ( ) . ConfigureAwait ( false ) ; if ( StringComparers . PropertyValues . Equals ( _currentTargetFramework , newTargetFramework ) ) { return _currentAggregateProjectContext ; } await DisposeAggregateProjectContextAsync ( _currentAggregateProjectContext ) . ConfigureAwait ( false ) ; } else { var activeProjectConfiguration = _commonServices . ActiveConfiguredProject . ProjectConfiguration ; var knownProjectConfigurations = await _commonServices . Project . Services . ProjectConfigurationsService . GetKnownProjectConfigurationsAsync ( ) . ConfigureAwait ( false ) ; if ( knownProjectConfigurations . All ( c => c . IsCrossTargeting ( ) ) && _currentAggregateProjectContext . HasMatchingTargetFrameworks ( activeProjectConfiguration , knownProjectConfigurations ) ) { return _currentAggregateProjectContext ; } previousContextToDispose = _currentAggregateProjectContext ; } } else { newTargetFramework = ( string ) await projectProperties . TargetFramework . GetValueAsync ( ) . ConfigureAwait ( false ) ; } await _commonServices . ThreadingService . SwitchToUIThread ( ) ; await _activeProjectConfigurationRefreshService . RefreshActiveProjectConfigurationAsync ( ) . ConfigureAwait ( false ) ; _currentAggregateProjectContext = await _contextProvider . Value . CreateProjectContextAsync ( ) . ConfigureAwait ( false ) ; _currentTargetFramework = newTargetFramework ; if ( previousContextToDispose != null ) { await DisposeAggregateProjectContextAsync ( previousContextToDispose ) . ConfigureAwait ( false ) ; } return _currentAggregateProjectContext ; } ) . ConfigureAwait ( false ) ; }
Ensures that  is updated for the latest target frameworks from the project properties
and returns this value.
Ensures that is updated for the latest target frameworks from the project properties and returns this value .
// Ensure that only single thread is attempting to create a project context. // Check if we have already computed the project context. // For non-cross targeting projects, we can use the current project context if the TargetFramework hasn't changed. // For cross-targeting projects, we need to verify that the current project context matches latest frameworks targeted by the project. // If not, we create a new one and dispose the current one. // Dispose the old workspace project context for the previous target framework. // Check if the current project context is up-to-date for the current active and known project configurations. // Force refresh the CPS active project configuration (needs UI thread). // Create new project context. // Dispose the old project context, if one exists.