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
ThreadPoolScheduler.SchedulePeriodic throws ArgumentOutOfRangeException when the period is negative (less than TimeSpan.Zero). Like the TaskPool variant, a strictly negative periodic interval is rejected as an invalid value before any other work is done.
Solutions
- Pass a zero or positive TimeSpan.
- Clamp negative computed periods to TimeSpan.Zero before the call.
- Fix the computation/parsing that produced the negative value.
Example fix
// before var period = TimeSpan.FromMilliseconds(intervalMs); // intervalMs = -250 scheduler.SchedulePeriodic(state, period, next => next); // after var period = TimeSpan.FromMilliseconds(Math.Max(0, intervalMs)); scheduler.SchedulePeriodic(state, period, next => next);
Defensive patterns
Strategy: validation
Validate before calling
if (period < TimeSpan.Zero) throw new InvalidOperationException($"Negative period {period}");
scheduler.SchedulePeriodic(state, period, action); Try / catch
try { scheduler.SchedulePeriodic(state, period, action); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "period") { log.LogError("Period must be non-negative, got {Period}", period); } Prevention
- Sanitize durations parsed from config/env before scheduling.
- Use checked subtraction and guard reversed time ranges.
When it happens
Trigger: Calling scheduler.SchedulePeriodic(state, TimeSpan.FromSeconds(-1), action) or any computed negative duration.
Common situations: Reversed subtraction for the interval, misparsed config values ('-5s'), or unit conversion mistakes when migrating from milliseconds/int APIs.
Related errors
- period (Parameter 'period')
- Specified argument was out of the range of valid values…
- period (Specified argument was out of the range of valid…
- Specified argument was out of the range of valid values…
- 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/12ddf0e653d14067.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.cs:132
//
return new StopwatchImpl();
}
/// <summary>
/// Schedules a periodic piece of work, using a System.Threading.Timer 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 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));
}
if (period == TimeSpan.Zero)
{
return new FastPeriodicTimer<TState>(state, action);
}
return new PeriodicTimer<TState>(state, period, action);
}
private sealed class FastPeriodicTimer<TState> : IDisposable
{
private TState _state;View on GitHub (pinned to 94b5d5ab91)