Skip to content

Migrate CreateWindowsSdkKnownFrameworkReferences to IMultiThreadableTask#53951

Open
SimaTian wants to merge 2 commits intodotnet:mainfrom
SimaTian:migrate-create-windows-sdk-known-framework-references
Open

Migrate CreateWindowsSdkKnownFrameworkReferences to IMultiThreadableTask#53951
SimaTian wants to merge 2 commits intodotnet:mainfrom
SimaTian:migrate-create-windows-sdk-known-framework-references

Conversation

@SimaTian
Copy link
Copy Markdown
Member

Migrates \CreateWindowsSdkKnownFrameworkReferences\ to support \IMultiThreadableTask.

Changes

  • Pattern A (pure in-memory): attribute + interface + stub TaskEnvironment. Task only computes framework-reference profiles from inputs; zero file I/O, zero env-var reads.
  • Replaces 4 string-literal metadata keys with \MetadataKeys.*\ constants.
  • Adds 3 behavioral test methods with 8 concurrent scenarios using start-gate pattern.

Addresses review feedback from #53116

  • ✅ Start-gate pattern (no Barrier + Parallel.For).
  • ✅ Dedicated per-task test file.
  • ✅ MetadataKeys constants replace string literals.
  • ✅ Tests use \�wait Task.WhenAll\ (fixes xUnit1031).

Supersedes

Part of the split of stuck merge-group PR #53116. This is the 2-of-5 split for \CreateWindowsSdkKnownFrameworkReferences.

SimaTian and others added 2 commits April 17, 2026 11:04
Task is pure in-memory with no file I/O or environment dependencies.
Applied attribute-only migration pattern:
- Implemented IMultiThreadableTask interface
- Added TaskEnvironment nullable property (for API consistency)
- Replaced metadata string literals with MetadataKeys constants

Added comprehensive multi-threading tests:
- Concurrent execution with varied inputs (8 scenarios)
- Used start-gate pattern with ManualResetEventSlim + Task.Run to avoid Barrier+Parallel.For deadlock
- Verified output correctness across different input modes
- Tested error cases under concurrent execution
- All metadata references use MetadataKeys constants

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- TaskEnvironment? -> TaskEnvironment under #nullable disable to fix CS8632 with TreatWarningsAsErrors
- Replace Task.WaitAll+.Result with async/await Task.WhenAll (xUnit1031)
- Fix scenario 4 expected count: 5 profiles per supported SDK version; two versions -> 10 items

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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

Migrates CreateWindowsSdkKnownFrameworkReferences to explicitly support MSBuild multi-threaded execution by implementing IMultiThreadableTask, and adds dedicated concurrency-focused unit tests to validate deterministic outputs and thread-safety.

Changes:

  • Update CreateWindowsSdkKnownFrameworkReferences to implement IMultiThreadableTask (adds TaskEnvironment property).
  • Replace several metadata string literals with MetadataKeys.* constants.
  • Add a new unit test file covering concurrency scenarios and concurrent error-case behavior.

Reviewed changes

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

File Description
src/Tasks/Microsoft.NET.Build.Tasks/CreateWindowsSdkKnownFrameworkReferences.cs Implements IMultiThreadableTask and uses MetadataKeys constants for selected metadata.
src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenACreateWindowsSdkKnownFrameworkReferencesMultiThreading.cs Adds dedicated behavioral + concurrent execution tests (including start-gate concurrency patterns).

const int concurrency = 8;
var taskInstances = new CreateWindowsSdkKnownFrameworkReferences[concurrency];
var executeTasks = new Task<bool>[concurrency];
var startGate = new ManualResetEventSlim(false);
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

ManualResetEventSlim implements IDisposable; consider declaring this start gate as using var (or disposing in a finally) to avoid leaking a wait handle if the test fails early.

Suggested change
var startGate = new ManualResetEventSlim(false);
using var startGate = new ManualResetEventSlim(false);

Copilot uses AI. Check for mistakes.
[Fact]
public async Task ErrorCasesAreConcurrentlySafe()
{
var startGate = new ManualResetEventSlim(false);
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

ManualResetEventSlim should be disposed. Using using var startGate = new ManualResetEventSlim(false); would ensure the wait handle is released even if assertions fail.

Suggested change
var startGate = new ManualResetEventSlim(false);
using var startGate = new ManualResetEventSlim(false);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants