dotnet/wpf · error · ArgumentException

SR.CurrentDispatcherNotFound

Error message

SR.CurrentDispatcherNotFound

What it means

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.

Solutions

  1. Create the TextFormatter on the UI thread (or after Dispatcher.CurrentDispatcher has been initialized) and pass it to the worker
  2. Explicitly create a Dispatcher for the thread first: var d = Dispatcher.CurrentDispatcher; if (d != null) use FromCurrentDispatcher
  3. Use TextFormatter.Create() (thread-affine instance not tied to a Dispatcher) instead when no Dispatcher is available
  4. Marshal the formatting work to the STA UI thread via Dispatcher.Invoke

Example fix

// before
var tf = TextFormatter.FromCurrentDispatcher(TextFormattingMode.Display); // on background thread
// after
Dispatcher.CurrentDispatcher; // ensure dispatcher exists
var tf = TextFormatter.FromCurrentDispatcher(TextFormattingMode.Display);
// or simply: var tf = TextFormatter.Create(TextFormattingMode.Display);
Defensive patterns

Strategy: validation

Validate before calling

if (Dispatcher.CurrentDispatcher == null) throw new InvalidOperationException("No WPF Dispatcher on this thread"); var tf = TextFormatter.FromCurrentDispatcher(TextFormattingMode.Display);

Type guard

bool HasDispatcher() => Dispatcher.CurrentDispatcher != null;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/textformatting/TextFormatter.cs:122

        internal static TextFormatter FromCurrentDispatcher()
        {
            return FromCurrentDispatcher(TextFormattingMode.Ideal);
        }

        /// <summary>
        /// Client to get TextFormatter associated with the current dispatcher
        /// </summary>
        /// <remarks>
        /// This method is available internally. It is exclusively used by Presentation Framework UIElement 
        /// through friend assembly mechanics to quickly reuse the default TextFormatter retained in the current
        /// dispatcher of the running thread. 
        /// </remarks>
        internal static TextFormatter FromCurrentDispatcher(TextFormattingMode textFormattingMode)
        {
            Dispatcher dispatcher = Dispatcher.CurrentDispatcher;

            if (dispatcher == null)
                throw new ArgumentException(SR.CurrentDispatcherNotFound);

            TextFormatter defaultTextFormatter;
            if (textFormattingMode == TextFormattingMode.Display)
            {
                defaultTextFormatter = (TextFormatterImp)dispatcher.Reserved4;
            }
            else
            {
                defaultTextFormatter = (TextFormatterImp)dispatcher.Reserved1;
            }
                        
            if (defaultTextFormatter == null)
            {
                lock (_staticLock)
                {
                    if (defaultTextFormatter == null)
                    {
                        // Default formatter has not been created for this dispatcher,

View on GitHub (pinned to 81131a70a4)