dotnet/reactive · error · ArgumentOutOfRangeException
interval
Error message
interval
What it means
The Sample<TSource>(IObservable<TSource>, TimeSpan) operator throws ArgumentOutOfRangeException when the interval is negative (interval < TimeSpan.Zero). A sampling interval must be zero or positive; a negative due time is meaningless for a scheduler. Zero is allowed (samples as fast as the scheduler allows).
Solutions
- Validate the interval before calling Sample and clamp/reject negatives.
- Fix the interval computation so it cannot go negative (e.g., Math.Max(TimeSpan.Zero, diff)).
- If you meant 'sample as often as possible', pass TimeSpan.Zero explicitly rather than a negative value.
Example fix
// before var interval = TimeSpan.FromSeconds(endSeconds - startSeconds); // can be negative var sampled = source.Sample(interval); // ArgumentOutOfRangeException // after var interval = TimeSpan.FromSeconds(Math.Max(0, endSeconds - startSeconds)); var sampled = source.Sample(interval);
Defensive patterns
Strategy: validation
Validate before calling
if (interval < TimeSpan.Zero)
interval = TimeSpan.Zero; // or reject
var sampled = source.Sample(interval); Type guard
static bool IsValidInterval(TimeSpan interval) => interval >= TimeSpan.Zero;
Try / catch
try
{
var sampled = source.Sample(interval);
}
catch (ArgumentOutOfRangeException ex)
{
// log interval value; fall back to a default interval
var sampled = source.Sample(TimeSpan.FromSeconds(1));
} Prevention
- Clamp computed durations with Math.Max(TimeSpan.Zero, value).
- Reject negative duration config values at parse time.
- Watch for DateTime subtraction order when deriving intervals.
When it happens
Trigger: Calling Observable.Sample(source, TimeSpan.FromSeconds(-1)) or any TimeSpan built from a negative value (e.g., subtracting DateTime values in the wrong order, or a config value parsed with a leading minus).
Common situations: Computing the interval from a date difference (later - earlier reversed); reading a negative interval from app settings; sign error when converting seconds to TimeSpan.From*; user-supplied config accepted without validation.
Related errors
- duration
- period (Parameter 'period')
- Specified argument was out of the range of valid values…
- 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/68f89ecebd2c192e.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:855
/// <param name="source">Source sequence to sample.</param>
/// <param name="interval">Interval at which to sample. If this value is equal to TimeSpan.Zero, the scheduler will continuously sample the stream.</param>
/// <returns>Sampled observable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="interval"/> is less than TimeSpan.Zero.</exception>
/// <remarks>
/// Specifying a TimeSpan.Zero value for <paramref name="interval"/> doesn't guarantee all source sequence elements will be preserved. This is a side-effect
/// of the asynchrony introduced by the scheduler, where the sampling action may not execute immediately, despite the TimeSpan.Zero due time.
/// </remarks>
public static IObservable<TSource> Sample<TSource>(this IObservable<TSource> source, TimeSpan interval)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (interval < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(interval));
}
return s_impl.Sample(source, interval);
}
/// <summary>
/// Samples the observable sequence at each interval, using the specified scheduler to run sampling timers.
/// Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to sample.</param>
/// <param name="interval">Interval at which to sample. If this value is equal to TimeSpan.Zero, the scheduler will continuously sample the stream.</param>
/// <param name="scheduler">Scheduler to run the sampling timer on.</param>
/// <returns>Sampled observable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="interval"/> is less than TimeSpan.Zero.</exception>
/// <remarks>
/// Specifying a TimeSpan.Zero value for <paramref name="interval"/> doesn't guarantee all source sequence elements will be preserved. This is a side-effectView on GitHub (pinned to 94b5d5ab91)