{"record":{"id":"263295a943cbfc18","repo":"dotnet/wpf","slug":"sr-dispatcherhasshutdown","errorCode":null,"errorMessage":"SR.DispatcherHasShutdown","messagePattern":"SR\\.DispatcherHasShutdown","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs","lineNumber":304,"sourceCode":"        public static void Run()\n        {\n            PushFrame(new DispatcherFrame());\n        }\n\n        /// <summary>\n        ///     Push an execution frame.\n        /// </summary>\n        /// <param name=\"frame\">\n        ///     The frame for the dispatcher to process.\n        /// </param>\n        public static void PushFrame(DispatcherFrame frame)\n        {\n            ArgumentNullException.ThrowIfNull(frame);\n\n            Dispatcher dispatcher = Dispatcher.CurrentDispatcher;\n            if(dispatcher._hasShutdownFinished) // Dispatcher thread - no lock needed for read\n            {\n                throw new InvalidOperationException(SR.DispatcherHasShutdown);\n            }\n\n            if(frame.Dispatcher != dispatcher)\n            {\n                throw new InvalidOperationException(SR.MismatchedDispatchers);\n            }\n\n            if(dispatcher._disableProcessingCount > 0)\n            {\n                throw new InvalidOperationException(SR.DispatcherProcessingDisabled);\n            }\n\n            dispatcher.PushFrameImpl(frame);\n        }\n\n        /// <summary>\n        ///     Requests that all nested frames exit.\n        /// </summary>","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs#L286-L322","documentation":"Dispatcher.PushFrame throws InvalidOperationException with SR.DispatcherHasShutdown when the dispatcher for the current thread has already finished shutting down (_hasShutdownFinished is true). Once a Dispatcher has shut down, it can no longer process its message queue, so pushing a new nested message loop (a frame) is not allowed. WPF surfaces this as a plain InvalidOperationException with the localized message string.","triggerScenarios":"Calling Dispatcher.Run() or Dispatcher.PushFrame(new DispatcherFrame()) on a thread whose Dispatcher has already completed shutdown (e.g. after InvokeShutdown/BeginInvokeShutdown finished, or after Application exit processed). Calling PushFrame from within a shutdown-complete callback or after the message loop exited.","commonSituations":"Restarting a message pump on a UI thread after Application.Run returned; calling ShowDialog/PushFrame during shutdown sequences; unit tests that shut the dispatcher down then try to pump again; threads created with Run() whose Run loop returned but code keeps pumping.","solutions":["Do not call PushFrame/Run again on a thread whose dispatcher has shut down; create a new thread (with a new Dispatcher) instead.","Guard with Dispatcher.CurrentDispatcher.HasShutdownFinished and skip pumping when true.","Move the work that needs pumping onto a still-running dispatcher (e.g. the Application's UI thread) via Dispatcher.Invoke/InvokeAsync.","Fix code paths that call InvokeShutdown/BeginInvokeShutdown prematurely before all frames are done."],"exampleFix":"// before\nDispatcher.PushFrame(new DispatcherFrame());\n// after\nvar d = Dispatcher.CurrentDispatcher;\nif (!d.HasShutdownFinished)\n{\n    Dispatcher.PushFrame(new DispatcherFrame());\n}","handlingStrategy":"validation","validationCode":"if (Dispatcher.CurrentDispatcher.HasShutdownFinished)\n    return; // cannot pump anymore\nDispatcher.PushFrame(new DispatcherFrame());","typeGuard":"static bool CanPushFrame => !Dispatcher.CurrentDispatcher.HasShutdownFinished;","tryCatchPattern":null,"preventionTips":["Check HasShutdownFinished before any PushFrame/Run","Never restart a message pump after Application shutdown completes","Create dedicated threads (with their own Dispatcher) instead of reusing shut-down ones","Audit InvokeShutdown/BeginInvokeShutdown call sites for premature shutdown"],"tags":["wpf","dispatcher","shutdown","threading"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}