dotnet/wpf · error · InvalidOperationException

SR.VerifyAccess

Error message

SR.VerifyAccess

What it means

Dispatcher.VerifyAccess throws InvalidOperationException when the calling thread does not own (have access to) the Dispatcher — i.e. the call is not executing on the Dispatcher's thread. WPF UI objects and DispatcherObject-derived types require thread affinity; this is the enforced check.

Solutions

  1. Marshal to the UI thread: dispatcher.Invoke/InvokeAsync(() => { ... }) before touching the object
  2. Use Dispatcher.CheckAccess() to branch: run inline when on-thread, dispatch otherwise
  3. Prefer async/await with a captured UI SynchronizationContext (await inside the handler) instead of manual threads
  4. For cross-thread data updates, enable marshaling via Binding with automatic UI-thread sync where applicable

Example fix

// before
// worker thread:
statusText.Text = "Done"; // InvalidOperationException: VerifyAccess
// after
Dispatcher.InvokeAsync(() => statusText.Text = "Done");
Defensive patterns

Strategy: try-catch

Validate before calling

if (!dispatcher.CheckAccess()) { dispatcher.InvokeAsync(action); return; }
action();

Type guard

bool IsOnUiThread(DispatcherObject o) => o.Dispatcher.CheckAccess();

Try / catch

try { uiElement.Update(); } catch (InvalidOperationException) { App.Current.Dispatcher.InvokeAsync(() => uiElement.Update()); }

Prevention

When it happens

Trigger: Touching UI elements or DispatcherObject members from a background/worker thread, Task.Run, async continuation on the thread pool, or an event/callback raised on a non-UI thread.

Common situations: Updating a control's property from a network/database callback; raising PropertyChanged from a worker thread for a property bound with non-marshaling binding; timer callbacks (System.Timers.Timer) touching UI; unit tests calling dispatcher-bound APIs off-thread.

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/b5679d1d1d0ddbc7. Report an issue: GitHub.

Appendix: source

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

        /// <summary>
        ///     Verifies that the calling thread has access to this object.
        /// </summary>
        /// <remarks>
        ///     Only the dispatcher thread may access DispatcherObjects.
        ///     <p/>
        ///     This method is public so that derived classes can probe to
        ///     see if the calling thread has access to itself.
        /// </remarks>
        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        public void VerifyAccess()
        {
            if(!CheckAccess())
            {
                // Used to inline VerifyAccess.
                [DoesNotReturn]
                [MethodImpl(MethodImplOptions.NoInlining)]
                static void ThrowVerifyAccess()
                    => throw new InvalidOperationException(SR.VerifyAccess);

                ThrowVerifyAccess();
            }
        }

        /// <summary>
        ///     Begins the process of shutting down the dispatcher.
        /// </summary>
        /// <remarks>
        ///     This API demand unrestricted UI Permission
        /// </remarks>
        public void BeginInvokeShutdown(DispatcherPriority priority) // NOTE: should be Priority
        {

            BeginInvoke(priority, new ShutdownCallback(ShutdownCallbackInternal));
        }

        /// <summary>

View on GitHub (pinned to 81131a70a4)