Document [DoNotParallelize] defer-to-end ordering behaviour - #10245
Merged
Conversation
Rewrite the DoNotParallelizeAttribute XML doc to describe both guarantees (mutual exclusion and deferral to the end of the source's run), the actionable tail-latency cost, that deferred tests may not run at all when a run is canceled during the parallel phase, the no-op behaviour when parallelization is disabled, the three placements, and the relationship to [ResourceLock] (precedence wording aligned with ResourceLockAttribute). Add a deterministic acceptance test pinning the defer-to-end ordering. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 25872624-3e9c-4f84-b3c2-5ed114d8e7d2
Contributor
There was a problem hiding this comment.
Pull request overview
Documents [DoNotParallelize] ordering and cancellation behavior and adds an acceptance test for deferred execution.
Changes:
- Expands XML documentation for scheduling guarantees and scope.
- Adds a multi-targeted ordering acceptance test.
Show a summary per file
| File | Description |
|---|---|
DoNotParallelizeAttribute.cs |
Documents exclusion, deferral, cancellation, and resource-lock behavior. |
ParallelExecutionTests.cs |
Verifies deferred tests run after parallelizable tests. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Medium
This comment has been minimized.
This comment has been minimized.
Address PR review: the deferred-test cost extends the source's critical path, not necessarily the whole multi-source run; a DoNotParallelize test can still overlap with tests from other sources (which may run in separate hosts). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 25872624-3e9c-4f84-b3c2-5ed114d8e7d2
Contributor
🧪 Test quality grade — PR #10245
This advisory comment was generated automatically. Grades are heuristic
|
0101
approved these changes
Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was undocumented
[DoNotParallelize]'s XML doc described it only as "disables parallelization", but the attribute actually provides two guarantees at once:The deferral (guarantee 2) was invisible to users. A
[DoNotParallelize]test appearing last looks like a scheduling anomaly, and the attribute's true cost — a deferred test cannot overlap with anything, so its duration is added to the run rather than absorbed by parallel work — is easy to underestimate.This PR rewrites the XML doc to state both guarantees plainly, keeping the "per test source (assembly)" scope explicit so "runs last" is not misread in multi-source runs.
Cancellation interaction (new even for those who knew about the deferral)
Because the deferred set runs only after the parallelizable phase, a run canceled during the parallelizable phase can complete without executing any deferred tests. Traced in source: workers swallow
OperationCanceledExceptionsoTask.WhenAllcompletes normally and control reaches the deferred block, butExecuteTestsWithTestRunnerAsynccallsThrowIfCancellationRequested()before each test, so the first deferred test throws before running. "Runs last" and "may not run at all when canceled early" are both true — documented as such.Documentation-only — no behaviour change
This PR changes no scheduler behaviour. The deferral is long-standing shipped behaviour; the goal is to describe it accurately, not to change it. The only code change is the acceptance test below.
Acceptance test pins the ordering
Adds a deterministic (timing-free) acceptance test in
ParallelExecutionTests.cs: parallelizable tests increment a shared in-process counter, and the[DoNotParallelize]test asserts the counter already equals the full expected count — so it can only pass if it ran after all parallelizable tests finished. This prevents a future refactor from silently changing the ordering.Verified it can actually fail: against a deliberately reordered scheduler (deferred set run first) the test fails on all three TFMs (
expected 4, actual 0); reverting restores green (net8.0 / net10.0 / net462).RFC 004 intentionally left untouched
docs/RFCs/004-In-Assembly-Parallel-Execution.mdalready documents the deferral (lines 66-68), so it was intentionally not modified. The gap was in the XML doc, not the RFC.Follow-up: dotnet/docs
The public docs on learn.microsoft.com describe
[DoNotParallelize]only as disabling parallelization and omit both the deferral and the cancellation behaviour. Recommend filing adotnet/docsissue to update them — not done here (no cross-repo PR).