/mt implies inline task factories out of proc#12614
/mt implies inline task factories out of proc#12614JanProvaznik merged 8 commits intodotnet:mainfrom
Conversation
|
@JanProvaznik would it be possible to put the information about the 'force' flag on this new context as well, so that we could remove the use of the Trait check from the TaskHosts themselves? In general the use of Traits is harder to test than injecting the context object - it could allow for easier parallelization of tests. |
|
it's a good idea, though it does not help that much with testing since nontrivial amount of them are ~end to end so there is nowhere to inject the mockengine with that flag |
There was a problem hiding this comment.
Pull Request Overview
This PR fixes an issue where inline task factories failed to compile for out-of-process execution when the /mt (multi-threaded) flag was used. The solution adds an internal ITaskFactoryHostContext interface to expose the multi-threaded build state to task factories during initialization, enabling them to compile to disk instead of in-memory when needed for proper out-of-process execution.
Key changes include:
- Introduction of
ITaskFactoryHostContextinterface to expose build context to task factories - Updates to all inline task factories to check multi-threaded state and compile appropriately
- Comprehensive test coverage for the new functionality
Reviewed Changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/Framework/ITaskFactoryHostContext.cs |
New internal interface exposing multi-threaded build state and force out-of-process flag |
src/Build/Instance/TaskFactoryLoggingHost.cs |
Implements ITaskFactoryHostContext interface and stores build parameters |
src/Build/Instance/TaskRegistry.cs |
Threads BuildParameters through task factory initialization chain |
src/Tasks/RoslynCodeTaskFactory/RoslynCodeTaskFactory.cs |
Uses host context to determine compilation mode instead of relying solely on environment variables |
src/Tasks/CodeTaskFactory.cs |
Uses host context to determine compilation mode instead of relying solely on environment variables |
src/Tasks/XamlTaskFactory/XamlTaskFactory.cs |
Uses host context to determine compilation mode instead of relying solely on environment variables |
src/UnitTests.Shared/MockEngine.cs |
Implements ITaskFactoryHostContext for testing with configurable properties |
src/Tasks.UnitTests/RoslynCodeTaskFactory_Tests.cs |
Adds comprehensive unit tests for multi-threaded compilation behavior |
src/Tasks.UnitTests/CodeTaskFactoryTests.cs |
Adds comprehensive unit tests for multi-threaded compilation behavior |
src/Tasks.UnitTests/XamlTaskFactory_Tests.cs |
Adds comprehensive unit tests for multi-threaded compilation behavior |
src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs |
Updates task instantiation logic to consider multi-threaded mode for out-of-process execution |
src/Build/BackEnd/BuildManager/BuildManager.cs |
Updates cleanup logic to handle multi-threaded builds |
Fixes #12596
Context
Inline task factories must compile to disk (not in-memory) for out-of-process execution, but had no visibility into the
/mt(multi-threaded) flag during initialization. This caused inline tasks to fail or fall back to in-process execution when/mtwas used.Solution: Add internal
ITaskFactoryHostContextinterface to exposeBuildParameters.MultiThreadedto task factories, enabling compilation to disk when needed.Changes Made
New Interface (
src/Framework/ITaskFactoryHostContext.cs):Key Files Modified:
TaskFactoryLoggingHost- Implements interface, exposes multi-threaded stateTaskRegistry- ThreadsBuildParametersto factory initializationRoslynCodeTaskFactory,CodeTaskFactory,XamlTaskFactory- CheckITaskFactoryHostContext.IsMultiThreadedBuild, set_compileForOutOfProcessflagBuildManager- Cleanup uses_buildParameters.MultiThreadedTesting
Unit Tests (11 added, all passing ✅):
/mtflag verifying.inline_task.dllexecution in external task hostManual Test:
Notes
Performance Impact
Backward Compatibility
✅ Existing builds unaffected - Parameter defaults to
false, existing behavior preserved✅ Environment variable still works -
MSBUILDFORCEINLINETASKFACTORIESOUTOFPROCtakes precedence✅ No public API changes -
ITaskFactoryHostContextis internal✅ Graceful degradation - Null-safe with
?.operators, works if interface not implementedWhy This Approach?
✅ Pros:
BuildParametersTaskRegistry(which isITranslatable)ITaskFactoryHostContextin unit tests❌ Alternatives Rejected:
Initialize(), cannot be deferred/mt