dotnet/wpf · error · InvalidOperationException
The DispatcherPriorityAwaiter is invalid.
Error message
The DispatcherPriorityAwaiter is invalid.
What it means
DispatcherPriorityAwaitable's awaiter (OnCompleted) throws InvalidOperationException if the underlying _dispatcher is null. This happens when the awaiter instance was created through a default/invalid path rather than via Dispatcher.InvokeAsync or BeginInvoke, so there is no dispatcher to post the continuation to.
Solutions
- Obtain the awaiter only from Dispatcher.InvokeAsync(...).Task.GetAwaiter() or Dispatcher.Yield(priority) - never construct/default it yourself
- Await the awaitable exactly once; create a new one for each yield point
- Verify the code path sets a valid Dispatcher before OnCompleted is invoked if implementing a custom awaitable
- Refactor to plain Task.Yield() plus InvokeAsync if the custom priority-yield is not strictly needed
Example fix
// before var awaiter = default(DispatcherPriorityAwaitable).GetAwaiter(); await awaiter; // throws: invalid awaiter // after await Dispatcher.Yield(DispatcherPriority.Background);
Defensive patterns
Strategy: validation
Validate before calling
// Only obtain awaiters via supported APIs: var awaitable = Dispatcher.Yield(DispatcherPriority.Background); // not default(...)
Type guard
bool isValidAwaiter(DispatcherPriorityAwaiter a) => a is not null; // default-constructed awaiters are invalid // prefer: never construct/default the awaiter yourself
Try / catch
try
{
await dispatcherYieldAwaitable;
}
catch (InvalidOperationException ex) when (ex.Message.Contains("DispatcherPriorityAwaiter is invalid"))
{
// fix the awaitable source; do not retry the same invalid awaiter
} Prevention
- Await Dispatcher.Yield()/InvokeAsync results only; never default-construct awaiters
- Await each awaitable exactly once
- Do not cache awaiter instances across awaits
- Use Task.Yield() when custom priority is unnecessary
When it happens
Trigger: Awaiting a DispatcherPriorityAwaitable obtained outside the supported API surface, or awaiting the same awaiter twice after it was reset/default-constructed (internal _dispatcher field null).
Common situations: Misusing Dispatcher.Yield or a default(DispatcherPriorityAwaitable)-style path, or caching/reusing an awaiter across awaits in custom async helpers.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ElementNotAvailableException
- index
- Invalid priority range order.
- Invalid priority value.
- Invalid priority value.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/25a1b51993a8c6a2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherPriorityAwaiter.cs:56
}
/// <summary>
/// This awaiter is just a proxy for queuing the continuations, it
/// never completes itself, so it doesn't have any result.
/// </summary>
public void GetResult()
{
}
/// <summary>
/// This is called with the continuation, which is simply queued to
/// the Dispatcher at the priority specified to the constructor.
/// </summary>
public void OnCompleted(Action continuation)
{
if(_dispatcher == null)
{
throw new InvalidOperationException(SR.DispatcherPriorityAwaiterInvalid);
}
_dispatcher.InvokeAsync(continuation, _priority);
}
private readonly Dispatcher _dispatcher;
private readonly DispatcherPriority _priority;
}
}
View on GitHub (pinned to 81131a70a4)