dotnet/reactive · error · ArgumentNullException

dispatcher

Error message

dispatcher

What it means

The CoreDispatcherScheduler constructor throws ArgumentNullException when the passed CoreDispatcher is null. A scheduler without a dispatcher has nothing to schedule work on, so Rx rejects it at construction time rather than failing later on the first Schedule call.

Solutions

  1. Obtain the dispatcher on the UI thread: CoreWindow.GetForCurrentThread().Dispatcher.
  2. Use CoreDispatcherScheduler.Current instead of manually passing a dispatcher.
  3. If the dispatcher may be null, defer scheduler creation until the UI context is available (e.g. via CoreApplication.Run or Window.Dispatcher inside the view).

Example fix

// before
var sched = new CoreDispatcherScheduler(CoreWindow.GetForCurrentThread()?.Dispatcher); // may be null
// after
var window = CoreWindow.GetForCurrentThread();
if (window == null) throw new InvalidOperationException("Must be called on UI thread");
var sched = new CoreDispatcherScheduler(window.Dispatcher);
Defensive patterns

Strategy: type-guard

Validate before calling

var dispatcher = CoreWindow.GetForCurrentThread()?.Dispatcher;
if (dispatcher == null) throw new InvalidOperationException("must construct on UI thread");
var sched = new CoreDispatcherScheduler(dispatcher);

Type guard

bool HasDispatcher(CoreWindow w) => w?.Dispatcher is not null;

Try / catch

try { var sched = new CoreDispatcherScheduler(d); } catch (ArgumentNullException ex) when (ex.ParamName == "dispatcher") { /* defer to UI thread */ }

Prevention

When it happens

Trigger: new CoreDispatcherScheduler(null), commonly when the dispatcher was obtained from CoreWindow.GetForCurrentThread()?.Dispatcher or a Window whose dispatcher is unavailable off the UI thread.

Common situations: UWP apps capturing a dispatcher in a ViewModel that is constructed on a background thread, or storing Window/CoreWindow in a static that resolves to null at scheduler creation time.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Concurrency/CoreDispatcherScheduler.cs:30

namespace System.Reactive.Concurrency
{
    /// <summary>
    /// Represents an object that schedules units of work on a <see cref="CoreDispatcher"/>.
    /// </summary>
    /// <remarks>
    /// This scheduler type is typically used indirectly through the <see cref="Linq.CoreDispatcherObservable.ObserveOnCoreDispatcher{TSource}(IObservable{TSource})"/> and <see cref="Linq.CoreDispatcherObservable.SubscribeOnCoreDispatcher{TSource}(IObservable{TSource})"/> methods that use the current CoreDispatcher.
    /// </remarks>
    [CLSCompliant(false)]
    public sealed class CoreDispatcherScheduler : LocalScheduler, ISchedulerPeriodic
    {
        /// <summary>
        /// Constructs a <see cref="CoreDispatcherScheduler"/> that schedules units of work on the given <see cref="CoreDispatcher"/>.
        /// </summary>
        /// <param name="dispatcher">Dispatcher to schedule work on.</param>
        /// <exception cref="ArgumentNullException"><paramref name="dispatcher"/> is <c>null</c>.</exception>
        public CoreDispatcherScheduler(CoreDispatcher dispatcher)
        {
            Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
            Priority = CoreDispatcherPriority.Normal;           
        }

        /// <summary>
        /// Constructs a <see cref="CoreDispatcherScheduler"/> that schedules units of work on the given <see cref="CoreDispatcher"/> with the given priority.
        /// </summary>
        /// <param name="dispatcher">Dispatcher to schedule work on.</param>
        /// <param name="priority">Priority for scheduled units of work.</param>
        /// <exception cref="ArgumentNullException"><paramref name="dispatcher"/> is <c>null</c>.</exception>
        public CoreDispatcherScheduler(CoreDispatcher dispatcher, CoreDispatcherPriority priority)
        {
            Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
            Priority = priority;
        }

        /// <summary>
        /// Gets the scheduler that schedules work on the <see cref="CoreDispatcher"/> associated with the current Window.
        /// </summary>

View on GitHub (pinned to 94b5d5ab91)