msbuild
msbuild copied to clipboard
ProjectRootElement.Open always uses cache
If I create 2 objects of Microsoft.Build.Construction.ProjectRootElement using Open(string path) method, where the file path is same but the content is altered in between the calls, the 2nd Open call returns content from in memory cache and not file.
var filePath = @"C:\temp\AProject.csproj";
var projectRootElement1 = Microsoft.Build.Construction.ProjectRootElement.Open(filePath)
// pause the debugger
// alter the file content slightly on disk
// resume debugger
var projectRootElement2 = Microsoft.Build.Construction.ProjectRootElement.Open(filePath)
Result: The value of projectRootElement1.OuterElement is same as projectRootElement2.OuterElement, which should not be.
Reasoning: Cache is good for performance, but there should be a flag available in Open method which forces the algorithm to read from disk and not from cache.
Workaround:
This problem has been worked around by using XmlReader, which is in our control and not cache.
using (XmlReader reader = XmlReader.Create(filePath))
{
projectRootElement1 = Microsoft.Build.Construction.ProjectRootElement.Create(reader);
}
// pause the debugger
// alter the file content slightly on disk
// resume debugger
using (XmlReader reader = XmlReader.Create(filePath))
{
projectRootElement2 = ProjectRootElement.Create(reader);
}
Result: The value of projectRootElement1.OuterElement is not same as projectRootElement2.OuterElement, as expected.
Tested on: OS: Windows .NET Version: .NET 4.7.2 Framework
Perhaps you can use ProjectCollection.UnloadProject(ProjectRootElement) to remove from the cache.
Perhaps. I am not looking for a workaround, because I already have one. I am asking to either document the Open function stating that it reads from cache first..... or give developers a way to bypass cache.
The cache behavior is required in some scenarios for consistency. Consider a build that updates one of its imports--you want the whole build to see the same version. This has been an important requirement for some Live Unit Testing scenario builds.
So I think we should make sure to clarify this behavior in the docs.