Class VirtualTimeScheduler
An IScheduler that tracks a virtual clock instead of real time. Schedule(Action, TimeSpan) never
runs anything itself — it queues (dueTime, action) pairs. Nothing executes until AdvanceTo(TimeSpan)
or AdvanceBy(TimeSpan) moves the clock forward past their due time, at which point every action whose due
time has now been reached runs synchronously, in due-time order (ties broken by scheduling order). That
determinism is the entire point: it lets time-based operators (Delay, DebounceTime, Timer,
Retry's backoff, ...) be tested without real Thread.Sleep/ManualResetEventSlim waits.
Mirrors rxjs's VirtualTimeScheduler.
public class VirtualTimeScheduler : IScheduler
- Inheritance
-
System.ObjectVirtualTimeScheduler
- Implements
- Derived
Properties
Clock
The current virtual time. Only ever moves forward, and only via AdvanceTo(TimeSpan)/AdvanceBy(TimeSpan)/Start() — never on its own.
public TimeSpan Clock { get; }
Property Value
- TimeSpan
Now
Now, expressed as the virtual clock offset from the Unix epoch, purely to satisfy
the IScheduler contract (some future operator might read Now instead of taking a
relative due time). Prefer reading Clock directly in tests — it is the same value without
the epoch indirection.
public DateTimeOffset Now { get; }
Property Value
- DateTimeOffset
Methods
AdvanceBy(TimeSpan)
Moves the clock forward by time and runs every action due by the new clock value. Equivalent to AdvanceTo(Clock + time).
public void AdvanceBy(TimeSpan time)
Parameters
timeTimeSpanThe non-negative amount of virtual time to move the clock forward by.
AdvanceTo(TimeSpan)
Moves the clock forward to time, running every queued action whose due time is at or
before time, in due-time order (ties broken by scheduling order). Actions due strictly
after time are left queued untouched — advancing never runs anything past the target.
The clock always ends exactly at time, even if nothing was queued to run.
public void AdvanceTo(TimeSpan time)
Parameters
timeTimeSpanThe virtual time to advance the clock to; must be at or after the current Clock.
Schedule(Action, TimeSpan)
Queues action to run once the clock reaches Clock + dueTime. Returns a disposable that cancels the action if it hasn't run yet.
public IDisposable Schedule(Action action, TimeSpan dueTime)
Parameters
actionActionThe action to run once due.
dueTimeTimeSpanThe delay, relative to the current virtual Clock, after which to run
action. Negative values are clamped to zero.
Returns
- IDisposable
A disposable that cancels the action if it hasn't run yet.
Start()
Runs every currently- and subsequently-queued action to completion, however far into virtual time that takes (i.e. drains the queue, unlike AdvanceTo(TimeSpan) which stops at a fixed target). Guards against an action that reschedules itself forever with a hard iteration cap.
public void Start()