dotnet/reactive · error · ArgumentNullException

nameof(context)

Error message

nameof(context)

What it means

System.ArgumentNullException thrown by Observable.ObserveOn<TSource>(IObservable<TSource>, SynchronizationContext) when the context argument is null. The public wrapper validates both parameters before delegating to s_impl.ObserveOn, so a null SynchronizationContext is rejected immediately.

Solutions

  1. Capture SynchronizationContext.Current only on the UI thread (e.g. in the Form/WPF constructor) before background work starts.
  2. Fall back to a non-null context or switch to ObserveOn(dispatcher scheduler) when no context exists.
  3. Use WindowsFormsSynchronizationContext.Current or the DispatcherScheduler explicitly instead of a null Current.

Example fix

// before
var ctx = SynchronizationContext.Current; // null on background thread
source.ObserveOn(ctx);
// after
var ctx = SynchronizationContext.Current ?? new SynchronizationContext();
source.ObserveOn(ctx);
Defensive patterns

Strategy: validation

Validate before calling

var ctx = SynchronizationContext.Current ?? new SynchronizationContext();
var result = source.ObserveOn(ctx);

Type guard

bool HasSyncContext(SynchronizationContext c) => c is not null;

Try / catch

try { obs = source.ObserveOn(context); }
catch (ArgumentNullException ex) when (ex.ParamName == "context") { obs = source.ObserveOn(Scheduler.Default); }

Prevention

When it happens

Trigger: Calling source.ObserveOn(context) with context == null, e.g. SynchronizationContext.Current captured before a UI context existed (or on a background thread where it is null).

Common situations: Capturing SynchronizationContext.Current in a console/background-thread app where it is null; caching the context in a static initialized too early; running the same code under unit tests without a UI context.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Concurrency.cs:62

        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="context">Synchronization context to notify observers on.</param>
        /// <returns>The source sequence whose observations happen on the specified synchronization context.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is null.</exception>
        /// <remarks>
        /// This only invokes observer callbacks on a synchronization context. In case the subscription and/or unsubscription actions have side-effects
        /// that require to be run on a synchronization context, use <see cref="Observable.SubscribeOn{TSource}(IObservable{TSource}, SynchronizationContext)"/>.
        /// </remarks>
        public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, SynchronizationContext context)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            return s_impl.ObserveOn(source, context);
        }

        #endregion

        #region + SubscribeOn +

        /// <summary>
        /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
        /// see the remarks section for more information on the distinction between SubscribeOn and ObserveOn.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="scheduler">Scheduler to perform subscription and unsubscription actions on.</param>
        /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>

View on GitHub (pinned to 94b5d5ab91)