Error when using await with MessageDialog.ShowAsync
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
await with MessageDialog.ShowAsync is usually correct, so when it fails the problem is often somewhere else: the wrong thread, the wrong method signature, or overlapping dialog calls. The dialog API is asynchronous, but it still has UI-thread rules and app-lifecycle constraints that normal background code does not have.
Use an Async Method Signature
The basic pattern is simple:
And from an event handler:
async void is acceptable for UI event handlers, but avoid it in reusable logic methods.
UI Thread Affinity Matters
MessageDialog must be shown from UI context. If your code is running on a background thread, marshal back to the dispatcher first.
Without that handoff, you can get runtime errors that look like await problems even though the real issue is thread affinity.
Avoid Showing Multiple Dialogs at Once
Another common failure mode is overlap. UWP-style apps generally expect one dialog at a time for a window. If several async code paths all try to show a dialog simultaneously, one of them may fail.
A simple lock helps:
This is especially useful during bursty error handling.
Do Not Block Async UI Code
Calling .Wait() or .Result on asynchronous UI operations can deadlock or freeze the interface. If you already have an async dialog API, stay async all the way through.
That means:
- prefer
await - keep the calling chain async
- avoid sync wrappers around UI dialog calls
Most ShowAsync errors blamed on await are actually caused by trying to force async UI code into a synchronous flow.
Modern Stack Consideration
In newer UI stacks, ContentDialog is often preferred over MessageDialog for richer control and better app integration. But the same core ideas still apply: correct thread, correct lifecycle, one dialog at a time.
So even if the exact dialog type changes, the async design principles stay the same.
Dialog lifecycle also matters during navigation and shutdown. If a page is disappearing or the window is not active, a dialog request can fail even when the code is otherwise correctly awaited. Routing dialog requests through one UI-layer service often makes these lifecycle edges much easier to control.
If you need app-wide error dialogs, centralize dialog display behind one service on the UI layer. That prevents background code from trying to own dialog state directly and reduces repeated thread-affinity mistakes.
Common Pitfalls
- Calling
ShowAsyncfrom a non-UI thread. - Using
.Wait()or.Resulton an asynchronous UI operation. - Triggering multiple dialogs concurrently.
- Hiding the original exception and blaming
awaitinstead of thread or lifecycle issues. - Using
async voidwidely outside UI event handlers.
Summary
- '
await dialog.ShowAsync()is the correct basic pattern.' - The real failure is often UI-thread or lifecycle misuse, not
awaititself. - Marshal back to the dispatcher when code starts on a background thread.
- Prevent overlapping dialog calls in asynchronous error flows.
- Keep the entire call chain asynchronous instead of blocking on dialog results.

