Skip to content

Comments

Migrate 5 MSBuild tasks to IMultiThreadableTask (Group 3: Package Assets & App Host)#52938

Open
SimaTian wants to merge 2 commits intodotnet:mainfrom
SimaTian:merge-group-3
Open

Migrate 5 MSBuild tasks to IMultiThreadableTask (Group 3: Package Assets & App Host)#52938
SimaTian wants to merge 2 commits intodotnet:mainfrom
SimaTian:merge-group-3

Conversation

@SimaTian
Copy link
Member

Migrate 5 MSBuild tasks to IMultiThreadableTask (Group 3: Package Assets & App Host)

Context

This PR migrates 5 MSBuild tasks to support multithreaded execution by implementing IMultiThreadableTask.

Dependency: This PR is stacked on #52909 (polyfills PR) which adds the IMultiThreadableTask interface, TaskEnvironment, and AbsolutePath polyfills. The diff will reduce once that PR is merged.

Migrated Tasks

Task Pattern Changes
ResolvePackageAssets B (Interface) Absolutize AssetsFilePath and ProjectAssetsCacheFile via TaskEnvironment.GetAbsolutePath(); LockFileCache uses absolutized paths
CreateAppHost B (Interface) Absolutize AppHostSourcePath and AppHostDestinationDirectoryPath via TaskEnvironment.GetAbsolutePath(); #if NETFRAMEWORK guard on polyfill
GetDependsOnNETStandard B (Interface) Absolutize reference paths via TaskEnvironment.GetAbsolutePath(); separate Extensions.Tasks project
AllowEmptyTelemetry A (Attribute) Attribute-only — no forbidden APIs (pure telemetry toggle)
CheckForTargetInAssetsFile A (Attribute) Attribute-only — file I/O delegated to LockFileCache

Changes Per Task

Each task receives:

  • [MSBuildMultiThreadableTask] attribute
  • IMultiThreadableTask interface implementation (Pattern B tasks)
  • TaskEnvironment property (Pattern B tasks)
  • Forbidden API replacements (relative path -> TaskEnvironment.GetAbsolutePath())

New Test Files

  • GivenAResolvePackageAssetsMultiThreading.cs
  • GivenACreateAppHostMultiThreading.cs
  • GivenAGetDependsOnNETStandardMultiThreading.cs (in Extensions.Tasks.UnitTests)
  • GivenAAllowEmptyTelemetryMultiThreading.cs
  • GivenACheckForTargetInAssetsFileMultiThreading.cs

Other Modified Files

  • GivenAResolvePackageAssetsTask.cs — existing tests updated to provide TaskEnvironment
  • GivenAGetDependsOnNETStandardTask.cs — existing tests updated to provide TaskEnvironment
  • Microsoft.NET.Build.Tasks.UnitTests.csprojTaskEnvironmentHelper compile link added
  • Microsoft.NET.Build.Extensions.Tasks.UnitTests.csprojTaskEnvironmentHelper compile link added

Note on GetDependsOnNETStandard

This task is in the Microsoft.NET.Build.Extensions.Tasks project (separate from the main Build.Tasks project). Its test is in Extensions.Tasks.UnitTests. No conflicts with other tasks in this group.

Testing

  • Build.Tasks.UnitTests: 226 passed, 11 failed (pre-existing ToolsetInfo environment failures, unrelated)
  • Extensions.Tasks.UnitTests: 10 passed, 0 failed
  • All multithreading tests pass
  • No regressions

Copilot AI review requested due to automatic review settings February 10, 2026 13:16
Copy link
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

Migrates a set of SDK MSBuild tasks to support MSBuild multithreaded execution by marking them multi-threadable and (where needed) implementing IMultiThreadableTask with TaskEnvironment-based absolute path resolution, plus adds supporting polyfills/tests.

Changes:

  • Mark tasks as multi-threadable ([MSBuildMultiThreadableTask]) and migrate key tasks to IMultiThreadableTask with TaskEnvironment.GetAbsolutePath(...).
  • Add TaskEnvironment test helper + new multithreading-focused unit tests for the migrated tasks.
  • Add .NET Framework-only polyfills for IMultiThreadableTask, TaskEnvironment, AbsolutePath, and drivers.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Tasks/Microsoft.NET.Build.Tasks/ResolvePackageAssets.cs Implements IMultiThreadableTask, adds TaskEnvironment, uses it to absolutize cache/assets paths.
src/Tasks/Microsoft.NET.Build.Tasks/CreateAppHost.cs Implements IMultiThreadableTask, adds TaskEnvironment, absolutizes apphost/source/destination/resource paths.
src/Tasks/Microsoft.NET.Build.Tasks/CheckForTargetInAssetsFile.cs Marks task as multi-threadable via attribute.
src/Tasks/Microsoft.NET.Build.Tasks/AllowEmptyTelemetry.cs Marks task as multi-threadable via attribute.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/TaskEnvironmentHelperTests.cs Adds tests validating TaskEnvironmentHelper behavior.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/TaskEnvironmentHelper.cs Adds helper for constructing TaskEnvironment in unit tests via proxy/reflection.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Microsoft.NET.Build.Tasks.UnitTests.csproj Adds package reference needed by new/updated tests.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenAResolvePackageAssetsTask.cs Updates existing tests to provide TaskEnvironment.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenAResolvePackageAssetsMultiThreading.cs Adds multithreading/migration verification tests for ResolvePackageAssets.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenACreateAppHostMultiThreading.cs Adds multithreading/migration verification tests for CreateAppHost.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenACheckForTargetInAssetsFileMultiThreading.cs Adds attribute-presence test for multi-threading marker.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenAAllowEmptyTelemetryMultiThreading.cs Adds attribute-presence test for multi-threading marker.
src/Tasks/Microsoft.NET.Build.Extensions.Tasks/GetDependsOnNETStandard.cs Implements IMultiThreadableTask, adds TaskEnvironment, absolutizes reference paths.
src/Tasks/Microsoft.NET.Build.Extensions.Tasks.UnitTests/Microsoft.NET.Build.Extensions.Tasks.UnitTests.csproj Links TaskEnvironmentHelper into extensions task tests.
src/Tasks/Microsoft.NET.Build.Extensions.Tasks.UnitTests/GivenAGetDependsOnNETStandardTask.cs Updates existing tests to provide TaskEnvironment.
src/Tasks/Microsoft.NET.Build.Extensions.Tasks.UnitTests/GivenAGetDependsOnNETStandardMultiThreading.cs Adds multithreading/migration verification tests for GetDependsOnNETStandard.
src/Tasks/Common/TaskEnvironment.cs Adds .NET Framework polyfill for TaskEnvironment.
src/Tasks/Common/ProcessTaskEnvironmentDriver.cs Adds .NET Framework polyfill driver for environment/path resolution.
src/Tasks/Common/ITaskEnvironmentDriver.cs Adds .NET Framework polyfill interface for TaskEnvironment drivers.
src/Tasks/Common/IMultiThreadableTask.cs Adds .NET Framework polyfill for IMultiThreadableTask.
src/Tasks/Common/AbsolutePath.cs Adds .NET Framework polyfill for AbsolutePath.

Copy link
Member Author

@SimaTian SimaTian left a comment

Choose a reason for hiding this comment

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

Addressed review comments:

  1. ProcessStartInfo.Environment: Fixed in polyfills PR (#52909) - now uses EnvironmentVariables which is available on net472.
  2. TaskEnvironment null validation: By design, MSBuild always populates TaskEnvironment before task execution. Adding explicit null checks would add defensive code that never executes in practice. The = null! annotation is not used because these files have #nullable disable. If the team prefers explicit validation, happy to add it.
  3. CreateAppHost TaskEnvironment: Same as above - MSBuild guarantees population.
  4. AbsolutePath.IsPathFullyQualified: Fixed in polyfills PR (#52909) - now correctly rejects drive-relative paths like \foo on Windows. Only UNC, drive-rooted, and extended paths are accepted as fully qualified.

All branches rebased on updated polyfills and force-pushed.

Copy link
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

Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.

@SimaTian SimaTian self-assigned this Feb 11, 2026
@SimaTian SimaTian force-pushed the merge-group-3 branch 4 times, most recently from 99300c3 to bfe2cb6 Compare February 22, 2026 15:01
Migrate AllowEmptyTelemetry, CheckForTargetInAssetsFile, CreateAppHost,
ResolvePackageAssets, and GetDependsOnNETStandard to use TaskEnvironment
for path resolution.

- Add [MSBuildMultiThreadableTask] attribute and IMultiThreadableTask
- Use TaskEnvironment.GetAbsolutePath for relative path resolution
- Add TaskTestEnvironment test infrastructure
- Add multithreading and absolute-path tests
These assertions are redundant - the interface implementation is already
verified by the compiler. Attribute-presence tests are sufficient.

Co-authored-by: Copilot <[email protected]>
@SimaTian
Copy link
Member Author

@dotnet/domestic-cat
Hello, I've run into a following issue:
the test is using msbuild.exe from Visual Studio 18 Insiders, and
since IMultiThreadableTask is a polyfill, an older MSBuild version won't set TaskEnvironment at all. So
either the MSBuild version doesn't support this interface yet, or the task needs to self-initialize

Can you suggest how to best work around that please? These changes are something we need as a part of making MSBuild Multithreading work. (other merge groups will most likely be affected as well, so let's just use this one as a representative sample)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant