dotnet/reactive · error · ArgumentNullException

control

Error message

control

What it means

The second validation in ControlObservable.SubscribeOn throws ArgumentNullException with parameter name 'control' when the Windows Forms Control is null. The control is required to build the ControlScheduler that marshals subscription to the UI thread.

Solutions

  1. Pass a valid non-null Control instance.
  2. Ensure InitializeComponent has run and the control reference is assigned before subscribing.
  3. If the control may be absent, skip the SubscribeOn call or fall back to a different scheduler.

Example fix

// before
var sub = source.SubscribeOn(this.statusStrip1); // statusStrip1 is null
// after
if (this.statusStrip1 != null)
    var sub = source.SubscribeOn(this.statusStrip1);
Defensive patterns

Strategy: validation

Validate before calling

if (control == null || control.IsDisposed)
    throw new InvalidOperationException("Target control unavailable");
var sub = source.SubscribeOn(control);

Type guard

static bool IsUsable(Control c) => c is { IsDisposed: false, IsHandleCreated: true };

Try / catch

try { var sub = source.SubscribeOn(control); }
catch (ArgumentNullException ex) when (ex.ParamName == "control") { log.Error("Control was null at SubscribeOn"); }

Prevention

When it happens

Trigger: Calling source.SubscribeOn(null), typically when a control field/property is null because InitializeComponent has not run, the control was disposed, or a FindControl lookup failed.

Common situations: Code executing before the form's constructor finishes; controls removed from the layout and set to null; designer field renames leaving stale null references; unit tests without a real control.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/c428018e43bd9742. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Linq/ControlObservable.cs:36

        /// <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>
        public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, Control control)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));

View on GitHub (pinned to 94b5d5ab91)