dotnet/reactive · error · ArgumentOutOfRangeException
period
Error message
period
What it means
CoreDispatcherScheduler.SchedulePeriodic<TState>(state, period, action) throws ArgumentOutOfRangeException because 'period' is negative. A periodic timer cannot run at a negative interval; the WinRT dispatcher timer only accepts TimeSpan.Zero or positive periods, so Rx rejects negative values eagerly.
Solutions
- Pass a positive (or zero) TimeSpan as 'period'; clamp negative values with something like period < TimeSpan.Zero ? TimeSpan.Zero : period.
- Fix the computation producing the negative duration (e.g. use Math.Max(TimeSpan.Zero, target - now)).
- Validate configured interval values at startup before scheduling.
Example fix
// before var elapsed = DateTime.Now - dueTime; // negative when dueTime is in the future scheduler.SchedulePeriodic(0, elapsed, Tick); // after var period = DateTime.Now < dueTime ? dueTime - DateTime.Now : TimeSpan.Zero; scheduler.SchedulePeriodic(0, period, Tick);
Defensive patterns
Strategy: validation
Validate before calling
// csharp
if (period < TimeSpan.Zero)
period = TimeSpan.Zero; // or throw with your own message
scheduler.SchedulePeriodic(state, period, action); Type guard
null
Try / catch
// csharp
try { d = scheduler.SchedulePeriodic(state, period, action); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "period") { log.Error("Negative periodic period", ex); d = Disposable.Empty; } Prevention
- Compute periods with Math.Max(TimeSpan.Zero, ...) when using elapsed-time arithmetic
- Validate configured intervals at application startup
- Unit-test interval computations with edge-case clocks
When it happens
Trigger: Calling SchedulePeriodic with a negative TimeSpan, e.g. SchedulePeriodic(state, TimeSpan.FromSeconds(-1), action), often from a computed duration like a negative difference between DateTimes or a misconfigured setting.
Common situations: Computing the period from (target - DateTime.Now) after the target has already passed; config/app-setting values parsed with a minus sign; arithmetic sign errors when building polling intervals.
Related errors
- ArgumentOutOfRangeException: period (Specified argument was…
- ArgumentOutOfRangeException: period…
- period (Parameter 'period')
- throw new ArgumentOutOfRangeException(nameof(period));
- period
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/9144e7da7212f364.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Concurrency/CoreDispatcherScheduler.cs:234
/// <summary>
/// Schedules a periodic piece of work on the dispatcher, using a <see cref="DispatcherQueueTimer"/> object.
/// </summary>
/// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
/// <param name="state">Initial state passed to the action upon the first iteration.</param>
/// <param name="period">Period for running the work periodically.</param>
/// <param name="action">Action to be executed, potentially updating the state.</param>
/// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
/// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
{
//
// According to MSDN documentation, the default is TimeSpan.Zero, so that's definitely valid.
// Empirical observation - negative values seem to be normalized to TimeSpan.Zero, but let's not go there.
//
if (period < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(period));
}
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
var timer = CreateDispatcherQueue().CreateTimer();
var state1 = state;
timer.Tick += (o, e) =>
{
state1 = action(state1);
};
timer.Interval = period;
timer.Start();View on GitHub (pinned to 94b5d5ab91)