Repository navigation
Cancel the async action's token off the caller's thread in Stop [patch] - #110
Merged
Merged
Conversation
Stop() cancelled the run's token inline, and CancellationTokenSource runs token callbacks, and the continuations they complete, on the cancelling thread. An action waiting through ct.Register therefore ran its cleanup inside Stop(), blocking the caller (2 s in the report) or deadlocking a UI thread the cleanup marshalled back to, and a callback that threw escaped Stop() as an AggregateException. The cancel now runs on the thread pool. A throwing callback is kept for RethrowExceptions, which a restart clears like a failed run, and StopAsync waits for the cancel so the failure is recorded when it returns. Fixes #83 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017vfJW59k83EYpQhgtoH5Qc
… check [patch] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017vfJW59k83EYpQhgtoH5Qc
Contributor
Author
|
CI note:
I'll re-run the failed job once when the rest of the run finishes. If it fails the same way again, the bound needs a separate fix on Generated by Claude Code |
|
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.



Fixes #83
What was wrong
StopCorecalledActionCancellation.Cancel()inline.CancellationTokenSource.Cancel()runs the token's callbacks, and any continuations they complete, on the thread that cancels. With anAsyncActionthat waits throughct.Register(() => tcs.TrySetCanceled()), the action's catch/finally cleanup therefore ran insideStop():Stop()was blocked for as long as the cleanup took (2 s in the report).Stop()(andStopAsync()/Dispose()) as anAggregateException.Change
StopCorehands the cancel to the thread pool (CancelAction), still outside the lock. It keeps theObjectDisposedExceptionguard for a run that finishes first.CancellationFailure.RethrowExceptionsreports it when the run itself has nothing to report, and a restart clears it the same way it discards a failed run's exception.StopAsyncalso awaits the handed-off cancel, so a callback failure has been recorded by the time it returns.StopGenerationis still bumped synchronously under the lock, so a dispatched run that has not begun is skipped (The action can still start after Stop() returns and PollingTask completes, and there is no public way to wait for it #67).StopAsyncstill waits for the loop and the run.Stoprow and CLAUDE.md now describe this.Tests
StopDoesNotRunTheAsyncActionCleanupOnTheCallersThread: the repro from the issue, withStop()called from a dedicated thread the way a UI thread would call it. Without the fix,Stop()takes the full 10 s of cleanup and fails the< 5 sbound.AThrowingCancellationCallbackIsReportedRatherThanThrownFromStop: without the fix,Stop()throwsAggregateException(InvalidOperationException: callback failed). With it, neither stop throws andRethrowExceptionsreports the exception.I checked both tests against
main'sIntervalAction.csand both fail there. With the fix, the full suite passes (64/64, net10.0), and a Release build across all target frameworks succeeds with no warnings.This PR and #109 both touch
IntervalAction.csand the CLAUDE.md bullet list. They're independent, so whichever lands second may need a trivial rebase.Generated by Claude Code