Skip to content

Commit

Permalink
Fix WaitForNextTickAsync_CanceledWaitThenWaitAgain_Succeeds test (#54775
Browse files Browse the repository at this point in the history
)

There's a race condition in the test between the timer firing and cancellation being requested.  It repros more on Linux because there's a smaller quantum on Linux than on Windows.
  • Loading branch information
stephentoub committed Jun 26, 2021
1 parent c2e8973 commit 46b5fdc
Showing 1 changed file with 13 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,24 @@ public async Task WaitForNextTickAsync_CanceledWaitThenWaitAgain_Succeeds()
{
using var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(1));

ValueTask<bool> task = timer.WaitForNextTickAsync(new CancellationToken(true));
Assert.ThrowsAny<OperationCanceledException>(() => task.Result);

var cts = new CancellationTokenSource();
task = timer.WaitForNextTickAsync(cts.Token);
ValueTask<bool> task = timer.WaitForNextTickAsync(cts.Token);
cts.Cancel();
Assert.Equal(cts.Token, Assert.ThrowsAny<OperationCanceledException>(() => task.Result).CancellationToken);

for (int i = 0; i < 10; i++)
try
{
Assert.True(await timer.WaitForNextTickAsync());
// If the task happens to succeed because the operation completes fast enough
// that it beats the cancellation request, then make sure it completed successfully.
Assert.True(await task);
}
catch (OperationCanceledException oce)
{
// Otherwise, it must have been canceled with the relevant token.
Assert.Equal(cts.Token, oce.CancellationToken);
}

// We should be able to await the next tick either way.
Assert.True(await timer.WaitForNextTickAsync());
}

private static void WaitForTimerToBeCollected(WeakReference<PeriodicTimer> timer, bool expected)
Expand Down

0 comments on commit 46b5fdc

Please sign in to comment.