dotnet/wpf · error · InvalidOperationException

SR.DispatcherProcessingDisabled

Error message

SR.DispatcherProcessingDisabled

What it means

Dispatcher.PushFrame throws InvalidOperationException with SR.DispatcherProcessingDisabled when the dispatcher's processing is currently disabled (its _disableProcessingCount is greater than zero), i.e. inside a Dispatcher.DisableProcessing scope. Message pumping is prohibited while processing is disabled to protect the dispatcher's internal state.

Solutions

  1. Move the PushFrame/ShowDialog/Invoke call outside the DisableProcessing scope.
  2. Remove the DisableProcessing wrapper if pumping is genuinely needed there.
  3. Disable processing only around short, non-reentrant code that never calls back into the dispatcher.
  4. Restructure so dependent work is queued with Dispatcher.InvokeAsync and executed after processing is re-enabled.

Example fix

// before
using (Dispatcher.CurrentDispatcher.DisableProcessing())
{
    Dispatcher.PushFrame(new DispatcherFrame());
}
// after
Dispatcher.PushFrame(new DispatcherFrame()); // outside the disabled scope
Defensive patterns

Strategy: validation

Validate before calling

// there is no public query; avoid pumping inside DisableProcessing scopes
using (Dispatcher.CurrentDispatcher.DisableProcessing())
{
    DoAtomicWork(); // must not call ShowDialog/PushFrame/Invoke
}
Dispatcher.PushFrame(new DispatcherFrame()); // outside the scope

Try / catch

try
{
    Dispatcher.PushFrame(frame);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("processing"))
{
    // we are inside DisableProcessing; defer the pump
}

Prevention

When it happens

Trigger: Calling PushFrame (directly or transitively, e.g. ShowDialog, WaitForPriority) inside a using Dispatcher.DisableProcessing() block, or inside code invoked under DispatcherProcessingDisabledMode; also raised from Invoke-like calls on the dispatcher while processing is disabled.

Common situations: Showing a modal dialog or pumping frames inside Dispatcher.DisableProcessing regions used for atomic updates; calling user code that pumps frames from within dispatcher-disabled sections (e.g. property change notifications during processing-disabled scopes).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

        /// </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)
            {
                dispatcher._exitAllFrames = true;

                // Post a message so that the message pump will wake up and
                // check our continue state.

View on GitHub (pinned to 81131a70a4)