dotnet/wpf · error · TimeoutException
The operation has timed out.
Error message
The operation has timed out.
What it means
Dispatcher.InvokeImpl waits for the invoked operation to complete under a CancellationToken tied to the timeout. If the wait ends because the cancellation token fired due to the timeout — and not because of an external cancellation — the dispatcher throws TimeoutException with the default message 'The operation has timed out.' This distinguishes a genuine timeout from a user-requested cancellation, which is rethrown as-is.
Solutions
- Increase the timeout, or pass TimeSpan.FromMilliseconds(-1) to wait indefinitely when acceptable.
- Avoid cross-thread Invoke when the target thread might wait on the caller (deadlock); use BeginInvoke/InvokeAsync (fire-and-forget) or marshal results with await.
- Catch TimeoutException at the call site and decide on retry/abort behavior.
- Ensure the UI thread's dispatcher queue is not starved (avoid 100+ ms synchronous work on it).
Example fix
// before
dispatcher.Invoke(() => Compute(), DispatcherPriority.Normal, TimeSpan.FromSeconds(1));
// after
var op = dispatcher.BeginInvoke(() => Compute());
// do not block the worker on the UI thread; continue asynchronously
op.Completed += (s, e) => { /* use op.Result */ }; Defensive patterns
Strategy: try-catch
Validate before calling
if (Dispatcher.FromThread(targetThread) == null || targetThread.IsAlive == false)
return; // do not block on a dead/absent dispatcher
dispatcher.Invoke(work, DispatcherPriority.Send, TimeSpan.FromSeconds(30)); Try / catch
try
{
dispatcher.Invoke(work, DispatcherPriority.Normal, TimeSpan.FromSeconds(30));
}
catch (TimeoutException)
{
// UI thread busy or deadlocked; retry with a longer timeout or go async
dispatcher.BeginInvoke(work);
} Prevention
- Never call blocking Invoke onto a thread that may itself be waiting on you (deadlock)
- Use BeginInvoke/InvokeAsync with await instead of synchronous cross-thread Invoke
- Give timeouts generous headroom for busy UI threads
- Keep UI-thread work slices short so dispatched items run promptly
When it happens
Trigger: Calling Dispatcher.Invoke (synchronous, cross-thread) where the dispatched operation cannot run within the specified timeout because the target dispatcher thread is busy/blocked with higher-priority or long-running work, or is itself deadlocked.
Common situations: Invoke from a worker thread onto a UI thread that is blocked waiting on the worker (classic deadlock until timeout); rendering/layout storms keeping the UI thread busy past the timeout; timeouts set too short (e.g. seconds) for heavy work.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Specified argument was out of the range of valid values…
- SR.AutomationTimeout
- The thread may not wait on operations that are already…
- timeout
- ElementNotAvailableException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/8c9a90b505e8d470.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs:1381
// This should not block because either the operation
// is using the old async sematics, or the operation
// completed successfully.
result = operation.Result;
}
catch(OperationCanceledException)
{
Debug.Assert(operation.Status == DispatcherOperationStatus.Aborted);
// New async semantics will throw an exception if the
// operation was aborted. Here we convert that
// exception into a timeout exception if the timeout
// has expired (admittedly a weak relationship
// assuming causality).
if (ctTimeout.IsCancellationRequested)
{
// The operation was canceled because of the
// timeout, throw a TimeoutException instead.
throw new TimeoutException();
}
else
{
// The operation was canceled from some other reason.
throw;
}
}
finally
{
ctTimeoutRegistration.Dispose();
ctsTimeout?.Dispose();
}
}
return result;
}
/// <summary>View on GitHub (pinned to 81131a70a4)