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
- Marshal to the UI thread: dispatcher.Invoke/InvokeAsync(() => { ... }) before touching the object
- Use Dispatcher.CheckAccess() to branch: run inline when on-thread, dispatch otherwise
- Prefer async/await with a captured UI SynchronizationContext (await inside the handler) instead of manual threads
- 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
- Check Dispatcher.CheckAccess() before touching DispatcherObject members from shared code
- Marshal via InvokeAsync/Invoke for all background-thread updates
- Use async/await so continuations resume on the UI context
- Prefer DispatcherTimer over System.Timers.Timer for UI updates
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
- parameter
- SR.ApplicationAlreadyRunning
- SR.Format(SR.WindowPassedShouldBeOnApplicationThread…
- Animation_Invalid_DefaultValue
- Cannot remove signature from read-only file.
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)