dotnet/reactive · error · InvalidOperationException

The current thread has no Dispatcher associated with it.

Error message

The current thread has no Dispatcher associated with it.

What it means

DispatcherScheduler.Current is a convenience accessor that grabs the Dispatcher of the calling thread via Dispatcher.FromThread. If the current thread has no Dispatcher (i.e. it is not a WPF UI thread), it throws InvalidOperationException with the NO_DISPATCHER_CURRENT_THREAD message.

Solutions

  1. Call DispatcherScheduler.Current only on the WPF UI thread; capture it once on the UI thread (e.g. in App startup) and reuse that instance.
  2. Construct the scheduler explicitly with the UI dispatcher: new DispatcherScheduler(Application.Current.Dispatcher) or DispatcherScheduler.From dispatcher of the Window.
  3. Use ObserveOnDispatcher()/SubscribeOnDispatcher() extension methods from within WPF code instead of manually fetching Current.

Example fix

// before
var sched = DispatcherScheduler.Current; // throws on background thread
// after
var sched = new DispatcherScheduler(Application.Current.Dispatcher);
Defensive patterns

Strategy: validation

Validate before calling

bool canUseCurrent = System.Windows.Threading.Dispatcher.FromThread(System.Threading.Thread.CurrentThread) != null;

Type guard

bool IsUiThread() => System.Windows.Threading.Dispatcher.FromThread(System.Threading.Thread.CurrentThread) != null;

Try / catch

try { var sched = DispatcherScheduler.Current; } catch (InvalidOperationException ex) when (ex.Message.Contains("Dispatcher")) { var sched = new DispatcherScheduler(Application.Current.Dispatcher); }

Prevention

When it happens

Trigger: Accessing DispatcherScheduler.Current from a background/thread-pool thread, a Task worker, a console Main thread, or any non-WPF thread where Dispatcher.FromThread returns null.

Common situations: Calling Current inside Subscribe callbacks or Rx operators that run on the thread-pool scheduler; unit tests running on plain MSTest/xUnit threads; building the scheduler during app startup before the UI thread is active.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive.Wpf/System.Reactive.Concurrency/DispatcherScheduler.cs:36

    /// This scheduler type is typically used indirectly through the <see cref="Linq.DispatcherObservable.ObserveOnDispatcher{TSource}(IObservable{TSource})"/> and <see cref="Linq.DispatcherObservable.SubscribeOnDispatcher{TSource}(IObservable{TSource})"/> methods that use the Dispatcher on the calling thread.
    /// </remarks>
    public class DispatcherScheduler : LocalScheduler, ISchedulerPeriodic
    {
        /// <summary>
        /// Gets the scheduler that schedules work on the current <see cref="System.Windows.Threading.Dispatcher"/>.
        /// </summary>
        [Obsolete(Constants_WindowsThreading.OBSOLETE_INSTANCE_PROPERTY)]
        public static DispatcherScheduler Instance => new(System.Windows.Threading.Dispatcher.CurrentDispatcher);

        /// <summary>
        /// Gets the scheduler that schedules work on the <see cref="System.Windows.Threading.Dispatcher"/> for the current thread.
        /// </summary>
        public static DispatcherScheduler Current
        {
            get
            {
                var dispatcher = System.Windows.Threading.Dispatcher.FromThread(Thread.CurrentThread)
                    ?? throw new InvalidOperationException(Strings_Wpf_WindowsThreading.NO_DISPATCHER_CURRENT_THREAD);
                return new DispatcherScheduler(dispatcher);
            }
        }

        /// <summary>
        /// Constructs a <see cref="DispatcherScheduler"/> that schedules units of work on the given <see cref="System.Windows.Threading.Dispatcher"/>.
        /// </summary>
        /// <param name="dispatcher"><see cref="DispatcherScheduler"/> to schedule work on.</param>
        /// <exception cref="ArgumentNullException"><paramref name="dispatcher"/> is <c>null</c>.</exception>
        public DispatcherScheduler(System.Windows.Threading.Dispatcher dispatcher)
        {
            Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
            Priority = System.Windows.Threading.DispatcherPriority.Normal;

        }

        /// <summary>
        /// Constructs a <see cref="DispatcherScheduler"/> that schedules units of work on the given <see cref="System.Windows.Threading.Dispatcher"/> at the given priority.

View on GitHub (pinned to 94b5d5ab91)