{"record":{"id":"9186f2dc11bc7fcb","repo":"dotnet/wpf","slug":"processing-is-disabled-while-the-dispatcher-is-in-this-state","errorCode":null,"errorMessage":"Processing is disabled while the Dispatcher is in this state.","messagePattern":"Processing is disabled while the Dispatcher is in this state\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs","lineNumber":2213,"sourceCode":"        private void TranslateAndDispatchMessage(ref MSG msg)\n        {\n            bool handled = false;\n\n            handled = ComponentDispatcher.RaiseThreadMessage(ref msg);\n\n            if(!handled)\n            {\n                UnsafeNativeMethods.TranslateMessage(ref msg);\n                UnsafeNativeMethods.DispatchMessage(ref msg);\n            }\n        }\n\n        private IntPtr WndProcHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)\n        {\n            WindowMessage message = (WindowMessage)msg;\n            if(_disableProcessingCount > 0)\n            {\n                throw new InvalidOperationException(SR.DispatcherProcessingDisabledButStillPumping);\n            }\n\n            if(message == WindowMessage.WM_DESTROY)\n            {\n                if(!_hasShutdownStarted && !_hasShutdownFinished) // Dispatcher thread - no lock needed for read\n                {\n                    // Aack!  We are being torn down rudely!  Try to\n                    // shut the dispatcher down as nicely as we can.\n                    ShutdownImpl();\n                }\n            }\n            else if(message == _msgProcessQueue)\n            {\n                ProcessQueue();\n            }\n            else if(message == WindowMessage.WM_TIMER && (int) wParam == TIMERID_BACKGROUND)\n            {\n                // This timer is just used to process background operations.","sourceCodeStart":2195,"sourceCodeEnd":2231,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs#L2195-L2231","documentation":"WPF's Dispatcher prohibits re-entrant message processing while processing is disabled (when _disableProcessingCount > 0, set via Dispatcher.DisableProcessing). If a window message arrives and the WndProcHook is entered while processing is disabled, the Dispatcher throws InvalidOperationException because pumping messages in a disabled state would violate its reentrancy guarantees.","triggerScenarios":"Calling Dispatcher.DisableProcessing() and then performing an operation that pumps messages (e.g. showing a modal dialog, waiting on a dispatcher operation) so WndProcHook receives a message while _disableProcessingCount > 0.","commonSituations":"Developers disabling dispatcher processing to block background reentrancy but then calling APIs that implicitly pump messages (MessageBox, drag-drop, Wait on a DispatcherOperation) on the dispatcher thread.","solutions":["Remove the surrounding DisableProcessing/EnableProcessing scope before any call that can pump messages","Ensure DisableProcessing is only used for short, non-pumping critical sections","Use Dispatcher.PushFrame-free alternatives (e.g. async/await) instead of blocking waits inside disabled regions","Wrap the region in try/finally so EnableProcessing is always called and the count does not leak"],"exampleFix":"// before\nusing (Dispatcher.CurrentDispatcher.DisableProcessing())\n{\n    MessageBox.Show(\"done\"); // pumps messages -> throws\n}\n// after\nMessageBox.Show(\"done\");\nusing (Dispatcher.CurrentDispatcher.DisableProcessing())\n{\n    DoCriticalWork();\n}","handlingStrategy":"try-catch","validationCode":"// Only pump-free work inside disabled regions\nbool safe = Dispatcher.CurrentDispatcher.DisableProcessingCountIsZero(); // custom check via reflection if needed","typeGuard":null,"tryCatchPattern":"try\n{\n    workThatMayPump();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Processing is disabled\"))\n{\n    logger.LogWarning(\"Attempted message pumping while dispatcher processing disabled\");\n}","preventionTips":["Never show modal dialogs or block-wait inside DisableProcessing scopes","Keep disabled regions short and pump-free","Always EnableProcessing in finally","Prefer async/await over reentrancy suppression"],"tags":["dispatcher","reentrancy","wpf","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"}