Repository navigation
Fix disposal completion and preserve transparent enqueue forwarding - #40
Merged
Merged
Conversation
dombrovsky
force-pushed
the
issue-39-thread-flow-disposal
branch
from
October 20, 2026 03:07
5bb679c to
7deb974
Compare
dombrovsky
marked this pull request as ready for review
October 20, 2026 03:54
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.
Thread-affine flows could leave caller-facing Enqueue tasks incomplete after disposal because typed and convenience async wrappers outlived queue shutdown. Return the typed execution item's completion task directly and forward it through convenience overloads. Retain ExecutionItem.Cancel.
Pipeline forwarding does not convert an exception thrown before an operation task is returned into a completion outcome. Returned task failures retain completion middleware behavior. Pipelines enforce their own middleware-lifetime and admission invariants without probing terminal disposal. Accepted child execution and independent completion continuations stay tracked until quiescence, including when outer middleware throws or times out. Explicit Submit retains its admission-decision/completion-task contract.
TaskFlowSchedulerAdapter, cancellation scope, cancel-previous, timeout, and WhenAnyCancelRest retain their base-branch implementations. The adapter leaves Task.Factory.StartNew exceptions alone, including its TaskSchedulerException wrapping. Existing async wrappers retain task-based rejection and their original resource ownership. Tests distinguish these behaviors from immediate pipeline forwarding rejection.
The pipeline invokes enqueue before handing the returned task to observation. The observation helper retains the continuation's activity until its task settles; releasing that activity when invocation returns could let accepted work outlive its middleware lifetime. Observation now sits outside the invocation try/catch, making the handoff explicit.
Remaining extension changes are direct task forwarding/validation in convenience and extended-state overloads, plus the one-line throttle fix that keeps its own admission rejection task-based. Rollback experiments with unchanged assertions found:
No public API signatures or analyzer suppressions were added. The universal synchronous-exception wording on ITaskScheduler was removed; raw adapter behavior has focused regression coverage instead.
Validation on
0632faa2e8ab011bd9b10ef70e77f878b37db4d6:Fixes #39