dotnet/reactive · error · ArgumentNullException
ArgumentNullException
Error message
ArgumentNullException
What it means
The Timer(TimeSpan, IAsyncScheduler) factory throws ArgumentNullException because the 'scheduler' parameter was null. Timer needs a scheduler to schedule the single emission at dueTime; the library validates this before creating the observable.
Solutions
- Pass TaskPoolAsyncScheduler.Default as the scheduler.
- If the scheduler comes from DI/configuration, verify registration and null-check it before calling Timer.
- Use the parameterless-scheduler overload Timer(TimeSpan dueTime), which defaults the scheduler internally.
Example fix
// before var timer = AsyncObservable.Timer(TimeSpan.FromSeconds(1), scheduler); // scheduler null from DI // after var timer = AsyncObservable.Timer(TimeSpan.FromSeconds(1), scheduler ?? TaskPoolAsyncScheduler.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (scheduler is null) throw new ArgumentNullException(nameof(scheduler)); var timer = AsyncObservable.Timer(dueTime, scheduler);
Type guard
bool HasScheduler(IAsyncScheduler s) => s is not null;
Try / catch
try
{
var timer = AsyncObservable.Timer(dueTime, scheduler);
}
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler")
{
var timer = AsyncObservable.Timer(dueTime); // default scheduler
} Prevention
- Check DI/configuration for the IAsyncScheduler binding before use.
- Use Timer(dueTime) without a scheduler when default behavior suffices.
- Watch argument order: dueTime first, scheduler second.
When it happens
Trigger: Calling AsyncObservable.Timer(dueTime, null) — e.g. a scheduler resolved from configuration or DI that is null, or a variable shadowing the intended scheduler.
Common situations: DI container failing to register an IAsyncScheduler implementation so the injected value is null; passing TimeSpan in the scheduler slot by mistake (overload argument-order mix-up).
Related errors
- Value cannot be null. (Parameter 'scheduler')
- comparer
- scheduler
- Value cannot be null. (Parameter 'disposable')
- Value cannot be null. (Parameter 'disposable')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/6a8157bbb6cf32f5.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Timer.cs:20
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information.
using System.Reactive.Concurrency;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<long> Timer(TimeSpan dueTime)
{
return Create<long>(observer => AsyncObserver.Timer(observer, dueTime));
}
public static IAsyncObservable<long> Timer(TimeSpan dueTime, IAsyncScheduler scheduler)
{
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return Create<long>(observer => AsyncObserver.Timer(observer, dueTime, scheduler));
}
public static IAsyncObservable<long> Timer(DateTimeOffset dueTime)
{
return Create<long>(observer => AsyncObserver.Timer(observer, dueTime));
}
public static IAsyncObservable<long> Timer(DateTimeOffset dueTime, IAsyncScheduler scheduler)
{
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return Create<long>(observer => AsyncObserver.Timer(observer, dueTime, scheduler));
}
public static IAsyncObservable<long> Timer(TimeSpan dueTime, TimeSpan period)View on GitHub (pinned to 94b5d5ab91)