dotnet/wpf · error · ArgumentException
Invalid priority value.
Error message
Invalid priority value.
What it means
DispatcherTimer.Initialize validates the priority twice: Dispatcher.ValidatePriority checks the value is a defined DispatcherPriority, and then Initialize rejects DispatcherPriority.Inactive specifically, because a timer with Inactive priority would never be processed. An invalid or Inactive priority throws ArgumentException/InvalidOperationException from the constructor.
Solutions
- Pass a valid active priority such as DispatcherPriority.Normal or Background - never Inactive
- Validate any config/interop integer with Enum.IsDefined(typeof(DispatcherPriority), value) before casting
- Use timer.IsEnabled = false to pause a timer instead of Inactive priority
- Centralize priority parsing in one helper that rejects unknown values early
Example fix
// before
var prio = (DispatcherPriority)configPriority; // e.g. 99 or Inactive
var timer = new DispatcherTimer(interval, prio, OnTick, dispatcher);
// after
var prio = Enum.IsDefined(typeof(DispatcherPriority), configPriority)
&& (DispatcherPriority)configPriority != DispatcherPriority.Inactive
? (DispatcherPriority)configPriority : DispatcherPriority.Normal;
var timer = new DispatcherTimer(interval, prio, OnTick, dispatcher); Defensive patterns
Strategy: validation
Validate before calling
if (!Enum.IsDefined(typeof(DispatcherPriority), priorityValue) ||
(DispatcherPriority)priorityValue == DispatcherPriority.Inactive)
throw new ArgumentException(nameof(priorityValue)); Type guard
bool IsValidTimerPriority(DispatcherPriority p) =>
Enum.IsDefined(p) && p != DispatcherPriority.Inactive; Try / catch
try
{
var timer = new DispatcherTimer(interval, priority, callback, dispatcher);
}
catch (ArgumentException ex)
{
logger.LogError(ex, "Invalid timer priority {Priority}", priority);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("priority"))
{
// Inactive priority passed; choose an active priority
} Prevention
- Only pass named DispatcherPriority constants, never raw ints from config
- Validate enum values with Enum.IsDefined before casting
- Use IsEnabled = false for paused timers instead of Inactive
- Keep a single helper for parsing priorities from external input
When it happens
Trigger: new DispatcherTimer(TimeSpan, (DispatcherPriority)99, callback, dispatcher) with an undefined priority value, or new DispatcherTimer(..., DispatcherPriority.Inactive, ...).
Common situations: Casting raw ints from config or interop into DispatcherPriority, refactoring code that stored priorities as numbers, or passing Inactive intending 'paused' semantics (which is IsEnabled's job).
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid priority range order.
- Invalid priority value.
- Invalid priority value.
- InvalidEnumArgumentException("defaultUpdateSourceTrigger"…
- InvalidEnumArgumentException(nameof(format), (int)format…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/4013ee1dfe003e8d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherTimer.cs:229
get
{
return _tag;
}
set
{
_tag = value;
}
}
private void Initialize(Dispatcher dispatcher, DispatcherPriority priority, TimeSpan interval)
{
// Note: all callers of this have a "priority" parameter.
Dispatcher.ValidatePriority(priority, "priority");
if(priority == DispatcherPriority.Inactive)
{
throw new ArgumentException(SR.InvalidPriority, nameof(priority));
}
_dispatcher = dispatcher;
_priority = priority;
_interval = interval;
}
private void Restart()
{
lock(_instanceLock)
{
if (_operation != null)
{
// Timer has already been restarted, e.g. Start was called form the Tick handler.
return;
}
// BeginInvoke a new operation.View on GitHub (pinned to 81131a70a4)