dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'dispatcher')

Error message

Value cannot be null. (Parameter 'dispatcher')

What it means

ObserveOn(source, dispatcher) requires a non-null WPF Dispatcher to marshal observations onto the UI thread. When the dispatcher parameter is null the library throws ArgumentNullException because there is no target context to schedule notifications on. The check happens synchronously at call time, before subscription.

Solutions

  1. Pass a valid Dispatcher, typically Application.Current.Dispatcher or Dispatcher.CurrentDispatcher for the UI thread.
  2. Guard with 'if (Application.Current != null)' or fall back to a non-dispatcher scheduler in headless/test hosts.
  3. Ensure the control/DispatcherObject is created on a thread that runs a Dispatcher before using its Dispatcher.

Example fix

// before
var onUi = source.ObserveOn(Application.Current.Dispatcher); // NRE if Application.Current is null
// after
var dispatcher = Application.Current?.Dispatcher ?? Dispatcher.CurrentDispatcher;
var onUi = source.ObserveOn(dispatcher);
Defensive patterns

Strategy: validation

Validate before calling

var dispatcher = Application.Current?.Dispatcher ?? Dispatcher.CurrentDispatcher; if (dispatcher == null) throw new InvalidOperationException("No dispatcher available in this host");

Type guard

bool hasDispatcher = Application.Current != null && Application.Current.Dispatcher != null;

Try / catch

try { var ui = source.ObserveOn(dispatcher); } catch (ArgumentNullException ex) when (ex.ParamName == "dispatcher") { var ui = source.ObserveOn(Scheduler.Default); }

Prevention

When it happens

Trigger: Calling source.ObserveOn(dispatcher) with a null Dispatcher, e.g. Dispatcher == null on a DispatcherObject created off the UI thread, or caching a Dispatcher in a static that was never set in a non-WPF (console/unit-test) host.

Common situations: Accessing Application.Current.Dispatcher when Application.Current is null (unit tests, background service); a control created on a non-UI thread whose Dispatcher is null; DI container failing to inject a Dispatcher; running Rx.Wpf code in a headless environment.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive.Wpf/System.Reactive.Linq/DispatcherObservable.cs:39

        /// <summary>
        /// Wraps the source sequence in order to run its observer callbacks on the specified dispatcher.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="dispatcher">Dispatcher whose associated message loop is used to notify observers on.</param>
        /// <returns>The source sequence whose observations happen on the specified dispatcher.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="dispatcher"/> is null.</exception>
        public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, Dispatcher dispatcher)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

            return ObserveOn_(source, dispatcher);
        }

        /// <summary>
        /// Wraps the source sequence in order to run its observer callbacks on the specified dispatcher.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="dispatcher">Dispatcher whose associated message loop is used to notify observers on.</param>
        /// <param name="priority">Priority to schedule work items at.</param>
        /// <returns>The source sequence whose observations happen on the specified dispatcher.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="dispatcher"/> is null.</exception>
        public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, Dispatcher dispatcher, DispatcherPriority priority)
        {
            if (source == null)
            {

View on GitHub (pinned to 94b5d5ab91)