dotnet/reactive · error · ArgumentOutOfRangeException
Specified argument was out of the range of valid values…
Error message
Specified argument was out of the range of valid values. (Parameter 'period')
What it means
DispatcherScheduler.SchedulePeriodic throws ArgumentOutOfRangeException when the period is less than TimeSpan.Zero. A negative periodic interval is meaningless; zero is accepted by this check (the guard is strictly < Zero), but negative values are rejected before the action null-check.
Solutions
- Clamp the period before scheduling: if (period < TimeSpan.Zero) period = TimeSpan.Zero;.
- Validate configuration values for polling intervals at startup and reject negatives early.
- Use Math.Max(TimeSpan.Zero, computedPeriod) for derived periods.
Example fix
// before scheduler.SchedulePeriodic(state, period, action); // period may be negative // after var safePeriod = period < TimeSpan.Zero ? TimeSpan.Zero : period; scheduler.SchedulePeriodic(state, safePeriod, action);
Defensive patterns
Strategy: validation
Validate before calling
if (period < TimeSpan.Zero) throw new InvalidOperationException($"period must be >= TimeSpan.Zero, was {period}"); Type guard
bool IsValidPeriod(TimeSpan p) => p >= TimeSpan.Zero;
Try / catch
try { scheduler.SchedulePeriodic(state, period, action); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "period") { /* clamp and retry */ } Prevention
- Clamp computed periods with Math.Max(TimeSpan.Zero, period).
- Validate configured intervals at startup.
- Beware of signed arithmetic when deriving periods from timestamps.
When it happens
Trigger: scheduler.SchedulePeriodic(state, TimeSpan.FromMilliseconds(-1), action) or a computed period from config/math that ends up negative (e.g. subtracting timestamps, misconfigured interval).
Common situations: Reading an interval from app config where the value is negative; computing period = next - now after `now` already passed; typos like FromSeconds(-1) in tests.
Related errors
- period
- Specified argument was out of the range of valid values…
- Specified argument was out of the range of valid values…
- period (Parameter 'period')
- Specified argument was out of the range of valid values…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/e213dfe4e4c9f4bd.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive.Wpf/System.Reactive.Concurrency/DispatcherScheduler.cs:184
return d;
}
/// <summary>
/// Schedules a periodic piece of work on the dispatcher, using a <see cref="System.Windows.Threading.DispatcherTimer"/> 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)
{
if (period < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(period));
}
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
var timer = new System.Windows.Threading.DispatcherTimer(Priority, Dispatcher);
var state1 = state;
timer.Tick += (s, e) =>
{
state1 = action(state1);
};
timer.Interval = period;
timer.Start();View on GitHub (pinned to 94b5d5ab91)