{"record":{"id":"ad3cbb6174e91b92","repo":"dotnet/wpf","slug":"sr-currentdispatchernotfound","errorCode":null,"errorMessage":"SR.CurrentDispatcherNotFound","messagePattern":"SR\\.CurrentDispatcherNotFound","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/textformatting/TextFormatter.cs","lineNumber":122,"sourceCode":"        internal static TextFormatter FromCurrentDispatcher()\n        {\n            return FromCurrentDispatcher(TextFormattingMode.Ideal);\n        }\n\n        /// <summary>\n        /// Client to get TextFormatter associated with the current dispatcher\n        /// </summary>\n        /// <remarks>\n        /// This method is available internally. It is exclusively used by Presentation Framework UIElement \n        /// through friend assembly mechanics to quickly reuse the default TextFormatter retained in the current\n        /// dispatcher of the running thread. \n        /// </remarks>\n        internal static TextFormatter FromCurrentDispatcher(TextFormattingMode textFormattingMode)\n        {\n            Dispatcher dispatcher = Dispatcher.CurrentDispatcher;\n\n            if (dispatcher == null)\n                throw new ArgumentException(SR.CurrentDispatcherNotFound);\n\n            TextFormatter defaultTextFormatter;\n            if (textFormattingMode == TextFormattingMode.Display)\n            {\n                defaultTextFormatter = (TextFormatterImp)dispatcher.Reserved4;\n            }\n            else\n            {\n                defaultTextFormatter = (TextFormatterImp)dispatcher.Reserved1;\n            }\n                        \n            if (defaultTextFormatter == null)\n            {\n                lock (_staticLock)\n                {\n                    if (defaultTextFormatter == null)\n                    {\n                        // Default formatter has not been created for this dispatcher,","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/textformatting/TextFormatter.cs#L104-L140","documentation":"TextFormatter.FromCurrentDispatcher throws ArgumentException with SR.CurrentDispatcherNotFound when Dispatcher.CurrentDispatcher returns null, meaning no WPF Dispatcher can be obtained for the calling thread. The library requires a Dispatcher because per-thread TextFormatter instances (like TextFormatterImp, cached in dispatcher.Reserved4) are dispatcher-affine. This guards against using text formatting APIs from a context without a message pump.","triggerScenarios":"Calling TextFormatter.FromCurrentDispatcher on a non-UI background thread before any WPF Dispatcher exists for it, or in environments where Dispatcher.CurrentDispatcher fails to create/return a dispatcher.","commonSituations":"Rendering text from a worker thread, console/unit-test harness without a WPF application context, library code invoked before Application.Run or on a plain ThreadPool thread.","solutions":["Create the TextFormatter on the UI thread (or after Dispatcher.CurrentDispatcher has been initialized) and pass it to the worker","Explicitly create a Dispatcher for the thread first: var d = Dispatcher.CurrentDispatcher; if (d != null) use FromCurrentDispatcher","Use TextFormatter.Create() (thread-affine instance not tied to a Dispatcher) instead when no Dispatcher is available","Marshal the formatting work to the STA UI thread via Dispatcher.Invoke"],"exampleFix":"// before\nvar tf = TextFormatter.FromCurrentDispatcher(TextFormattingMode.Display); // on background thread\n// after\nDispatcher.CurrentDispatcher; // ensure dispatcher exists\nvar tf = TextFormatter.FromCurrentDispatcher(TextFormattingMode.Display);\n// or simply: var tf = TextFormatter.Create(TextFormattingMode.Display);","handlingStrategy":"validation","validationCode":"if (Dispatcher.CurrentDispatcher == null) throw new InvalidOperationException(\"No WPF Dispatcher on this thread\"); var tf = TextFormatter.FromCurrentDispatcher(TextFormattingMode.Display);","typeGuard":"bool HasDispatcher() => Dispatcher.CurrentDispatcher != null;","tryCatchPattern":null,"preventionTips":["Create TextFormatter instances on the UI thread and share with workers","Prefer TextFormatter.Create() when a Dispatcher is not required","Never call dispatcher-affine WPF text APIs from plain ThreadPool threads without a dispatcher"],"tags":["wpf","dispatcher","threading","textformatting"],"backgroundTag":"missing-dependency","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"}