Sleep, delay, and cancellation — PrimeTime (NodaTime) stack
The PrimeTime (NodaTime) stack exposes synchronous Sleep and asynchronous DelayAsync APIs that accept NodaTime Duration values. It also includes GetTimeCancellationToken to produce a TimeCancellationTokenSource that auto-cancels after a clock-driven elapsed time.
ServiceCollection services = [];
services.AddPrimeClock();
await using ServiceProvider serviceProvider = services.BuildServiceProvider();
IPrimeClock primeClock = serviceProvider.GetRequiredService<IPrimeClock>();
Duration sleepDuration = _runMode == DemoRunMode.Long
? Duration.FromSeconds(1)
: Duration.FromMilliseconds(250);
Duration delayDuration = _runMode == DemoRunMode.Long
? Duration.FromSeconds(2)
: Duration.FromSeconds(1);
Duration cancellationAfter = _runMode == DemoRunMode.Long
? Duration.FromSeconds(2)
: Duration.FromMilliseconds(800);
ScenarioConsole.WriteLine($"Sleeping for {sleepDuration}...");
primeClock.Sleep(sleepDuration);
ScenarioConsole.WriteLine("Sleep completed.");
ScenarioConsole.WriteLine($"Running DelayAsync for {delayDuration}...");
await primeClock.DelayAsync(delayDuration, cancellationToken);
ScenarioConsole.WriteLine("DelayAsync completed.");
using TimeCancellationTokenSource timeout = primeClock.GetTimeCancellationToken(cancellationAfter);
try
{
ScenarioConsole.WriteLine($"Starting cancellable delay; timeout in {cancellationAfter}.");
await primeClock.DelayAsync(Duration.FromSeconds(10), timeout.Token);
ScenarioConsole.WriteLine("Delay completed before timeout.");
}
catch (OperationCanceledException)
{
ScenarioConsole.WriteLine("Delay canceled by time-based cancellation token.");
}
What to notice
primeClock.Sleep(Duration)blocks the calling thread for the specified duration. Under aPrimeTestClock, the call returns deterministically once virtual time is advanced.primeClock.DelayAsync(Duration, CancellationToken)is the awaitable counterpart and honors the supplied cancellation token.GetTimeCancellationToken(Duration)returns aTimeCancellationTokenSourcethat auto-cancels itsTokenafter the specified clock-time elapsed period — useful for awaitable timeouts that follow virtual time in tests.TimeSpanoverloads remain available from the shared contract for cross-stack code.
Related
- Concepts: Timers, daylight saving, and testing
- API:
IPrimeClock·TimeCancellationTokenSource