Fix ScheduledTaskExecutor deadlock when TrySetResult runs continuations inline by crnhrv · Pull Request #2953 · App-vNext/Polly (original) (raw)
Pull Request
The issue or feature being addressed
Fixes #2948 — ScheduledTaskExecutor deadlock when TrySetResult runs continuations inline.
Details on the issue fix or feature implementation
ScheduledTaskExecutor.ScheduleTask was creating its TaskCompletionSource<object> without TaskCreationOptions.RunContinuationsAsynchronously. This meant that when StartProcessingAsync called TrySetResult, any continuation awaiting the returned task could run inline on the executor's single processing thread. If that continuation blocked (e.g. by holding a lock and making a synchronous Polly call, or by waiting for a second scheduled task), the executor thread would stall and deadlock.
To fix we pass TaskCreationOptions.RunContinuationsAsynchronously to the TaskCompletionSource constructor, ensuring continuations are always sent to the thread pool rather than running inline.
A regression test is included that forces a continuation to run synchronously via TaskContinuationOptions.ExecuteSynchronously and has it block waiting for a second scheduled task. This deadlocks (and is cancelled after 250ms) without the fix.
Confirm the following
- I started this PR by branching from the head of the default branch
- I have targeted the PR to merge into the default branch
- I have included unit tests for the issue/feature
- I have successfully run a local build