MaterialDesignInXAML/MaterialDesignInXamlToolkit · error · InvalidOperationException
SnackbarMessageQueue must be created in a dispatcher thread
Error message
SnackbarMessageQueue must be created in a dispatcher thread
What it means
The single-argument constructor SnackbarMessageQueue(TimeSpan) resolves the current thread's Dispatcher via Dispatcher.FromThread(Thread.CurrentThread). On a thread with no dispatcher (a Task, thread-pool, or test thread) this returns null and the constructor throws InvalidOperationException, because the queue needs a dispatcher to schedule UI work.
Source
Thrown at src/MaterialDesignThemes.Wpf/SnackbarMessageQueue.cs:120
{
_waitHandle.Dispose();
_isDisposed = true;
}
_disposedWaitHandle.Set();
_disposedWaitHandle.Dispose();
}
}
#endregion
public SnackbarMessageQueue()
: this(TimeSpan.FromSeconds(3))
{
}
public SnackbarMessageQueue(TimeSpan messageDuration)
: this(messageDuration, Dispatcher.FromThread(Thread.CurrentThread)
?? throw new InvalidOperationException("SnackbarMessageQueue must be created in a dispatcher thread"))
{ }
public SnackbarMessageQueue(TimeSpan messageDuration, Dispatcher dispatcher)
{
_messageDuration = messageDuration;
_dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
}
//oh if only I had Disposable.Create in this lib :) tempted to copy it in like dragablz,
//but this is an internal method so no one will know my dirty Action disposer...
internal Action Pair(Snackbar snackbar)
{
if (snackbar is null) throw new ArgumentNullException(nameof(snackbar));
_pairedSnackbars.Add(snackbar);
return () => _pairedSnackbars.Remove(snackbar);
}View on GitHub (pinned to 98edec3a0b)
Solutions
- Construct the queue on the UI thread.
- Use the two-argument constructor and pass an explicit Dispatcher: new SnackbarMessageQueue(duration, Application.Current.Dispatcher).
- In tests, establish a Dispatcher (e.g. via a DispatcherSynchronizationContext on a dedicated STA thread) or pass Application.Current.Dispatcher.
Example fix
// before (Task thread has no dispatcher) var queue = await Task.Run(() => new SnackbarMessageQueue(TimeSpan.FromSeconds(3))); // after var queue = new SnackbarMessageQueue(TimeSpan.FromSeconds(3), Application.Current.Dispatcher);
Defensive patterns
Strategy: validation
Validate before calling
Dispatcher? d = Dispatcher.FromThread(Thread.CurrentThread);
var queue = d is not null
? new SnackbarMessageQueue(duration)
: new SnackbarMessageQueue(duration, Application.Current.Dispatcher); Type guard
Dispatcher.FromThread(Thread.CurrentThread) is not null
Prevention
- Prefer the two-argument constructor with an explicit Dispatcher.
- Construct the queue on the UI thread, never inside Task.Run.
- In tests, establish a Dispatcher before creating the queue.
When it happens
Trigger: Calling new SnackbarMessageQueue(duration) from a Task, thread-pool thread, or unit-test thread that has no WPF dispatcher.
Common situations: DI/async factory constructing the queue; background services; xUnit/nunit test threads; constructing the queue during static initialization off the UI thread.
Related errors
- SnackbarMessageQueue must be created by the same thread.
- Cannot get theme outside of a WPF application. Use {nameof(R
- Cannot set theme outside of a WPF application. Use {nameof(R
- Cannot get ThemeManager outside of a WPF application. Use {n
- Could not locate required resource with key(s) '{string.Join
AI-assisted analysis of MaterialDesignInXAML/MaterialDesignInXamlToolkit@98edec3a0b (2026-08-13).
Data as JSON: /api/errors/592c22978f3401ea.
Report an issue: GitHub.