dotnet/reactive · error · ArgumentNullException
throw new ArgumentNullException(nameof(scheduler));
Error message
throw new ArgumentNullException(nameof(scheduler));
What it means
The Sample<TSource>(source, interval, scheduler) overload throws ArgumentNullException when the scheduler argument is null. The scheduler drives the periodic sampling timer, so the operator requires a concrete IAsyncScheduler; it is checked after source validation.
Solutions
- Pass an explicit scheduler such as TaskPoolAsyncScheduler.Default or a local/new async scheduler
- When the scheduler is optional, write: scheduler ?? TaskPoolAsyncScheduler.Default
- Register the IAsyncScheduler in your DI container / fix the factory returning null
- Use the two-argument Sample(source, interval) overload, which defaults to TaskPoolAsyncScheduler.Default
Example fix
// before var sampled = src.Sample(period, scheduler); // scheduler from DI, may be null // after var sampled = src.Sample(period, scheduler ?? TaskPoolAsyncScheduler.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (scheduler is null) scheduler = TaskPoolAsyncScheduler.Default; var sampled = source.Sample(interval, scheduler);
Type guard
static bool HasScheduler(IAsyncScheduler? s) => s is not null;
Try / catch
try
{
var sampled = source.Sample(interval, scheduler);
}
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler")
{
sampled = source.Sample(interval, TaskPoolAsyncScheduler.Default);
} Prevention
- Always register IAsyncScheduler in the DI container
- Default optional schedulers to TaskPoolAsyncScheduler.Default at call sites
- Use the two-argument overload when no custom scheduler is needed
- Test scheduler resolution with a missing-registration scenario
When it happens
Trigger: Passing null as the IAsyncScheduler parameter — e.g. a scheduler resolved from configuration/DI that was never registered, a test double left unassigned, or an optional-scheduler code path passing null instead of the default.
Common situations: DI container missing an IAsyncScheduler registration; custom scheduler factory returning null on unsupported platform; migration from another Rx library whose overload defaulted the scheduler.
Related errors
- throw new ArgumentNullException(nameof(source));
- throw new ArgumentNullException(nameof(sampler));
- throw new ArgumentNullException(nameof(observer));
- throw new ArgumentNullException(nameof(source));
- Value cannot be null. (Parameter 'scheduler')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/6860abc8480e25be.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Sample.cs:58
return CreateAsyncObservable<TSource>.From(
source,
interval,
static async (source, interval, observer) =>
{
var (sourceSink, sampler) = await AsyncObserver.Sample(observer, interval).ConfigureAwait(false);
var sourceSubscription = await source.SubscribeSafeAsync(sourceSink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(sourceSubscription, sampler);
});
}
public static IAsyncObservable<TSource> Sample<TSource>(this IAsyncObservable<TSource> source, TimeSpan interval, IAsyncScheduler scheduler)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return CreateAsyncObservable<TSource>.From(
source,
(scheduler, interval),
static async (source, state, observer) =>
{
var (sourceSink, sampler) = await AsyncObserver.Sample(observer, state.interval, state.scheduler).ConfigureAwait(false);
var sourceSubscription = await source.SubscribeSafeAsync(sourceSink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(sourceSubscription, sampler);
});
}
}
public partial class AsyncObserver
{
public static (IAsyncObserver<TSource>, IAsyncObserver<TSample>) Sample<TSource, TSample>(IAsyncObserver<TSource> observer)View on GitHub (pinned to 94b5d5ab91)