dotnet/wpf · error · InvalidOperationException

SR.MismatchedDispatchers

Error message

SR.MismatchedDispatchers

What it means

Dispatcher.PushFrame throws InvalidOperationException with SR.MismatchedDispatchers when the DispatcherFrame passed in was created for (or associated with) a different Dispatcher than the one running on the current thread. Each frame records its owning Dispatcher, and PushFrame validates frame.Dispatcher == Dispatcher.CurrentDispatcher before pushing.

Solutions

  1. Create a new DispatcherFrame on the same thread you call PushFrame from.
  2. Ensure the frame's Dispatcher equals Dispatcher.CurrentDispatcher before pushing.
  3. Stop sharing frame instances across threads; make frames thread-local.
  4. If cross-thread work is intended, use Dispatcher.Invoke/InvokeAsync on the target dispatcher instead of pumping its frame from another thread.

Example fix

// before
private static readonly DispatcherFrame _frame = new DispatcherFrame();
Dispatcher.PushFrame(_frame);
// after
Dispatcher.PushFrame(new DispatcherFrame()); // created on the calling thread
Defensive patterns

Strategy: validation

Validate before calling

if (frame.Dispatcher != Dispatcher.CurrentDispatcher)
    frame = new DispatcherFrame(); // recreate on this thread
Dispatcher.PushFrame(frame);

Type guard

bool IsFrameForCurrentThread(DispatcherFrame f) => f.Dispatcher == Dispatcher.CurrentDispatcher;

Prevention

When it happens

Trigger: Calling PushFrame on thread A with a DispatcherFrame whose Dispatcher property points to thread B's dispatcher — typically a frame captured or created on another thread, or a shared static frame reused across threads.

Common situations: Caching a DispatcherFrame in a static/shared field and pumping it from multiple threads; creating a frame on the UI thread and pushing it from a worker; borrowing frames across modal-dialog helpers.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/6c6e085e9abe2c21. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs:309

        /// <summary>
        ///     Push an execution frame.
        /// </summary>
        /// <param name="frame">
        ///     The frame for the dispatcher to process.
        /// </param>
        public static void PushFrame(DispatcherFrame frame)
        {
            ArgumentNullException.ThrowIfNull(frame);

            Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
            if(dispatcher._hasShutdownFinished) // Dispatcher thread - no lock needed for read
            {
                throw new InvalidOperationException(SR.DispatcherHasShutdown);
            }

            if(frame.Dispatcher != dispatcher)
            {
                throw new InvalidOperationException(SR.MismatchedDispatchers);
            }

            if(dispatcher._disableProcessingCount > 0)
            {
                throw new InvalidOperationException(SR.DispatcherProcessingDisabled);
            }

            dispatcher.PushFrameImpl(frame);
        }

        /// <summary>
        ///     Requests that all nested frames exit.
        /// </summary>
        public static void ExitAllFrames()
        {

            Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
            if(dispatcher._frameDepth > 0)

View on GitHub (pinned to 81131a70a4)