Skip to content

Prefer dotnet MSBuild.dll for out-of-proc worker nodes in CLI scenarios#13452

Merged
rainersigwald merged 2 commits intomainfrom
yko/prefer-dotnet-host-for-cli-nodes
Mar 30, 2026
Merged

Prefer dotnet MSBuild.dll for out-of-proc worker nodes in CLI scenarios#13452
rainersigwald merged 2 commits intomainfrom
yko/prefer-dotnet-host-for-cli-nodes

Conversation

@YuliiaKovalova
Copy link
Copy Markdown
Member

@YuliiaKovalova YuliiaKovalova commented Mar 27, 2026

Summary

When MSBuild is launched via dotnet.exe (e.g. dotnet build, dotnet msbuild), BuildEnvironmentHelper resolves CurrentMSBuildExePath to MSBuild.exe (the AppHost) because it prefers the AppHost over MSBuild.dll. This causes all out-of-proc worker nodes to launch as MSBuild.exe processes instead of dotnet MSBuild.dll.

Problem

PR #13175 introduced the MSBuild AppHost (MSBuild.exe). After this change, dotnet build spawns worker nodes as MSBuild.exe processes. ETL trace analysis of OrchardCore NuGet restore shows a ~16% regression (61s -> 72s):

  • RestoreTask: 29,619ms -> 37,718ms (+27%)
  • ExecuteTask total: 207,854ms -> 232,996ms (+12%)
  • Same number of worker nodes (7), same build work (~1.03M build events)
  • JIT method counts are similar (116,545 vs 112,952) but CPU samples in JIT are ~17% higher per worker
  • The regression is spread across the entire process lifetime, not concentrated in startup

The root cause of the performance difference between MSBuild.exe and dotnet MSBuild.dll hosting is not fully understood from available ETL data. Reverting worker nodes to dotnet MSBuild.dll in CLI scenarios restores baseline performance.

@YuliiaKovalova YuliiaKovalova force-pushed the yko/prefer-dotnet-host-for-cli-nodes branch from 9d2ce02 to 235f003 Compare March 27, 2026 11:20
When MSBuild is launched via dotnet.exe (e.g. dotnet build, dotnet msbuild),
BuildEnvironmentHelper resolves CurrentMSBuildExePath to MSBuild.exe (the
AppHost) because it prefers .exe over .dll. This causes all out-of-proc
worker nodes to launch as MSBuild.exe AppHost processes, incurring native
bootstrap overhead per node.

This change detects when the current process is dotnet.exe and the resolved
MSBuild location is the AppHost, then substitutes MSBuild.dll so worker
nodes are launched via dotnet.exe instead. This only applies to regular
worker nodes (nodemode:1), not task host nodes (nodemode:2) which may
need the AppHost for COM host object support.

Fixes a ~16% regression in NuGet restore of OrchardCore (61s -> 72s)
introduced by the AppHost PR #13175.
@YuliiaKovalova YuliiaKovalova force-pushed the yko/prefer-dotnet-host-for-cli-nodes branch from 235f003 to d9bf159 Compare March 27, 2026 11:20
@YuliiaKovalova YuliiaKovalova marked this pull request as ready for review March 27, 2026 14:11
Copilot AI review requested due to automatic review settings March 27, 2026 14:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts out-of-proc worker node launching when MSBuild is running under dotnet.exe (CLI-hosted), preferring dotnet MSBuild.dll over the MSBuild app host to reduce native bootstrap overhead while keeping task host behavior unchanged.

Changes:

  • Extract NodeMode earlier in GetNodes() to enable mode-specific launch decisions.
  • On .NET Core, when CLI-hosted and launching regular worker nodes (/nodemode:1), substitute MSBuild.dll for MSBuild.exe if it exists alongside the app host.

@YuliiaKovalova YuliiaKovalova force-pushed the yko/prefer-dotnet-host-for-cli-nodes branch 2 times, most recently from 47c3b6e to e689cc0 Compare March 27, 2026 14:28
@YuliiaKovalova YuliiaKovalova requested a review from a team as a code owner March 27, 2026 14:28
@YuliiaKovalova YuliiaKovalova force-pushed the yko/prefer-dotnet-host-for-cli-nodes branch 2 times, most recently from 1aaacab to d1ba98d Compare March 27, 2026 15:11
@YuliiaKovalova YuliiaKovalova force-pushed the yko/prefer-dotnet-host-for-cli-nodes branch from d1ba98d to dd9439d Compare March 27, 2026 15:11
@JanProvaznik JanProvaznik added the merge-carefully Merge one at a time, verifying this doesn't break anything down the chain. label Mar 30, 2026
@rainersigwald
Copy link
Copy Markdown
Member

Tests on dotnet/dotnet#5751 suggest that this mitigates the NuGet Perf DDRIT problem so let's do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-carefully Merge one at a time, verifying this doesn't break anything down the chain.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants