dotnet / dotnet/msbuild

"Collection was modified" exception because of transitive project references

Open
#3,515 1 comment 3 reactions 0 assignees View on GitHub
triaged
Dominant language
C#
Stars
5.5k
Forks
1.5k
Avg merge
1d 8h
Merged PRs (30d)
141

Description

### Preconditions
I have 3 projects:
1. Common.csproj
```xml


netstandard2.0

```
2. Lib.csproj (referenes Common.csproj)
```xml


netstandard2.0



```
3. App.csproj (references Lib.csproj)
```xml


netstandard2.0



```

I performed packages restore and build all these projects.
Everything is ok so far.

### The issue

I want to build only **Common.csproj** and **App.csproj** and obtain some data via MsBuild API. I do it in the next way:
```C#

void Run()
{
...
DoBuildProject(commonXml);
DoBuildProject(appXml);
}

void DoBuildProject(ProjectRootElement xml)
{
var properties = new Dictionary();
properties["BuildProjectReferences"] = "False";
properties["TargetFramework"] = "netstandard2.0";

var project = new Project(xml, properties, null, ProjectCollection);
var projectInstance = BuildManager.GetProjectInstanceForBuild(project);
var buildRequestData = new BuildRequestData(projectInstance, new[] { "Build" }, HostServices, BuildRequestDataFlags.ProvideProjectStateAfterBuild);
var request = BuildManager.PendBuildRequest(buildRequestData);
request.ExecuteAsync(submission =>
{
foreach (var item in submission.BuildResult.ProjectStateAfterBuild.Items)
{
...
}
}, null);
```

And from time to time I get **Collection was modified** exception. That happens when "Common" project was already built and it's items are processed inside foreach loop. But at the same time "App" project is building and modifying the "Common" project instance.

As far as I understand MsBuild builds some targets (_GetTargetFrameworks_ for example) from project references (transitive). And I can not disable this by _BuildProjectReferences_ property.

My first idea was build a project graph, but it the case above "App" project has only one project reference to "Lib" project after evaluation. The "Common" reference is added in the _IncludeTransitiveProjectReferences_ target during build process.

So maybe you have an idea how to avoid concurrent project modifications in this case.
Thanks in advance!

### Environment data
`msbuild /version` output:
15.6.85.37198

OS info:
Windows 10 Pro, x64, build 17134.112

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.