diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/ProjectSystemProjectFactoryTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/ProjectSystemProjectFactoryTests.vb new file mode 100644 index 0000000000000..3b744dfa4fd93 --- /dev/null +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/ProjectSystemProjectFactoryTests.vb @@ -0,0 +1,38 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports System.Collections.Immutable +Imports System.Threading +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.CodeAnalysis.Workspaces.ProjectSystem +Imports Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem +Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework +Imports Roslyn.Test.Utilities + +Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim + <[UseExportProvider]> + Public Class ProjectSystemProjectFactoryTests + + Public Async Function ProjectInstantiatedWithCompilationOutputAssemblyFilePathCanBeChanged() As Task + Using environment = New TestEnvironment() + Dim creationInfo = New VisualStudioProjectCreationInfo() + creationInfo.CompilationOutputAssemblyFilePath = "C:\output\project.dll" + Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync( + "project1", LanguageNames.CSharp, creationInfo, CancellationToken.None) + + Dim projectInSolution = environment.Workspace.CurrentSolution.GetProject(project1.Id) + + Assert.Equal(creationInfo.CompilationOutputAssemblyFilePath, projectInSolution.CompilationOutputInfo.AssemblyPath) + + ' Change the path and ensure it's updated + Dim newOutputPath = "C:\output\new\project.dll" + project1.CompilationOutputAssemblyFilePath = newOutputPath + + Dim newProjectInSolution As Project = environment.Workspace.CurrentSolution.GetProject(project1.Id) + Assert.Equal(newOutputPath, newProjectInSolution.CompilationOutputInfo.AssemblyPath) + End Using + End Function + End Class +End Namespace diff --git a/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProjectFactory.cs b/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProjectFactory.cs index 7e23dcce25ad5..470a62bd9b5e8 100644 --- a/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProjectFactory.cs +++ b/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProjectFactory.cs @@ -165,6 +165,11 @@ await ApplyChangeToWorkspaceAsync(w => // Set this value early after solution is created so it is available to Razor. This will get updated // when the command line is set, but we want a non-null value to be available as soon as possible. + // + // Set the property in a batch; if we set the property directly we'll be taking a synchronous lock here and + // potentially block up thread pool threads. Doing this in a batch means the global lock will be acquired asynchronously. + var disposableBatchScope = await project.CreateBatchScopeAsync(CancellationToken.None).ConfigureAwait(false); + await using var _ = disposableBatchScope.ConfigureAwait(false); project.CompilationOutputAssemblyFilePath = creationInfo.CompilationOutputAssemblyFilePath; return project;