dotnet/reactive · error · ArgumentNullException
throw new ArgumentNullException(nameof(sampler));
Error message
throw new ArgumentNullException(nameof(sampler));
What it means
The Sample<TSource,TSample>(source, sampler) overload throws ArgumentNullException when the sampler observable is null. The sampler is the stream whose emissions trigger publishing the latest source value, so the operator requires both streams up front and validates them synchronously.
Solutions
- Create the sampler before calling Sample (e.g. AsyncObservable.Interval(period) or another hot stream)
- Guard at the composition site: if sampler == null, substitute AsyncObservable.Interval(defaultPeriod) or Empty
- Fix the factory/DI path that produced the null sampler
- Wrap in a helper that validates both arguments and throws a domain-specific error
Example fix
// before var sampled = prices.Sample(configuredSampler); // null when config missing // after var sampler = configuredSampler ?? AsyncObservable.Interval(TimeSpan.FromSeconds(1)); var sampled = prices.Sample(sampler);
Defensive patterns
Strategy: validation
Validate before calling
if (sampler is null) sampler = AsyncObservable.Interval(TimeSpan.FromSeconds(1)); var sampled = source.Sample(sampler);
Type guard
static bool HasSampler<TSample>(IAsyncObservable<TSample>? s) => s is not null;
Try / catch
try
{
var sampled = source.Sample(sampler);
}
catch (ArgumentNullException ex) when (ex.ParamName == "sampler")
{
sampler = AsyncObservable.Interval(defaultPeriod);
sampled = source.Sample(sampler);
} Prevention
- Default missing samplers to a timed interval stream instead of null
- Construct sampler and source together in a factory that returns a named pair
- Use nullable reference type annotations on fields holding the sampler
- Cover sampler construction in unit tests with config-missing scenarios
When it happens
Trigger: Calling source.Sample(sampler) with a null sampler — e.g. a timer/sampler stream that failed to initialize, a conditional that returns null instead of a default sampler, or passing the result of a lookup that missed.
Common situations: Sampler built from a configuration-driven interval where config was missing and the builder returned null; unit test forgot to set up the sampler; a NuGet/version change made a previously non-null sampler nullable.
Related errors
- throw new ArgumentNullException(nameof(source));
- throw new ArgumentNullException(nameof(source));
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'onNext')
- Value cannot be null. (Parameter 'onError')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/99a638ac2b776c7d.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Sample.cs:19
// Licensed to the .NET Foundation under one or more agreements.
// 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.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Sample<TSource, TSample>(this IAsyncObservable<TSource> source, IAsyncObservable<TSample> sampler)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (sampler == null)
throw new ArgumentNullException(nameof(sampler));
return CreateAsyncObservable<TSource>.From(
source,
sampler,
static async (source, sampler, observer) =>
{
var (sourceSink, samplerSink) = AsyncObserver.Sample<TSource, TSample>(observer);
var sourceSubscription = await source.SubscribeSafeAsync(sourceSink).ConfigureAwait(false);
var samplerSubscription = await sampler.SubscribeSafeAsync(samplerSink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(sourceSubscription, samplerSubscription);
});
}
public static IAsyncObservable<TSource> Sample<TSource>(this IAsyncObservable<TSource> source, TimeSpan interval)
{
if (source == null)View on GitHub (pinned to 94b5d5ab91)