dotnet/reactive · error · ArgumentNullException
source
Error message
source
What it means
ControlObservable.SubscribeOn is an extension method that marshals subscription of the source sequence onto the Windows Forms control's message loop via a ControlScheduler. It validates both arguments and throws ArgumentNullException naming 'source' when the observable is null. The library cannot wrap a null sequence.
Solutions
- Ensure the source IObservable<TSource> is non-null before calling SubscribeOn.
- Fix the producer that is returning null instead of a sequence (use Observable.Empty or Observable.Throw).
- Guard with a null check or coalesce to an empty sequence before subscribing.
Example fix
// before var sub = maybeSource.SubscribeOn(this.pictureBox); // after var sub = (maybeSource ?? Observable.Empty<Image>()).SubscribeOn(this.pictureBox);
Defensive patterns
Strategy: validation
Validate before calling
if (source == null) source = Observable.Empty<TSource>();
if (control == null) throw new InvalidOperationException("Control not initialized");
var sub = source.SubscribeOn(control); Type guard
static bool CanSubscribeOn<TSource>(IObservable<TSource> source, Control control) => source is not null && control is not null;
Try / catch
try { var sub = source.SubscribeOn(control); }
catch (ArgumentNullException ex) when (ex.ParamName is "source" or "control") { log.Error($"SubscribeOn got null {ex.ParamName}"); } Prevention
- Have services return Observable.Empty instead of null
- Subscribe only after form initialization (e.g. in OnLoad, not in the constructor)
- Use null-coalescing fallbacks at composition sites
When it happens
Trigger: Calling nullSource.SubscribeOn(someControl), often when the observable comes from a method that returned null, a failed service call, or an uninitialized field.
Common situations: UI data-binding code where the observable-producing service returns null on error; refactors where a reactive property was never initialized; WinForms screens composed before the data source is ready.
Related errors
- control
- source
- dispatcher
- dispatcher (Parameter 'dispatcher')
- Value cannot be null. (Parameter 'subscribeAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2434c38eba5d87d0.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Linq/ControlObservable.cs:31
public static class ControlObservable
{
/// <summary>
/// Wraps the source sequence in order to run its subscription and unsubscription logic on the Windows Forms message loop associated with the specified control.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="control">Windows Forms control whose associated message loop is used to perform subscription and unsubscription actions on.</param>
/// <returns>The source sequence whose subscriptions and unsubscriptions happen on the Windows Forms message loop associated with the specified control.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="control"/> is null.</exception>
/// <remarks>
/// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified control.
/// In order to invoke observer callbacks on the specified control, e.g. to render results in a control, use <see cref="ObserveOn"/>.
/// </remarks>
public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, Control control)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (control == null)
{
throw new ArgumentNullException(nameof(control));
}
return Synchronization.SubscribeOn(source, new ControlScheduler(control));
}
/// <summary>
/// Wraps the source sequence in order to run its observer callbacks on the Windows Forms message loop associated with the specified control.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="control">Windows Forms control whose associated message loop is used to notify observers on.</param>
/// <returns>The source sequence whose observations happen on the Windows Forms message loop associated with the specified control.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="control"/> is null.</exception>View on GitHub (pinned to 94b5d5ab91)