What is the proper way to show a message dialog due to a caught exception?
I originally tried
try
{
await DoSomething();
}
catch(InvalidOperation
Edit: After Hans' comment about other issues, I ended up solving it by creating the following class:
public static class MessageDialogDisplayer
{
private static readonly ConcurrentQueue<MessageDialog> _dialogQueue;
private static readonly CancellationTokenSource _cancellationTokenSource;
static MessageDialogDisplayer()
{
_dialogQueue = new ConcurrentQueue<MessageDialog>();
_cancellationTokenSource = new CancellationTokenSource();
new Task(DisplayQueuedDialogs, _cancellationTokenSource.Token).Start();
}
public static void DisplayDialog(MessageDialog dialog)
{
_dialogQueue.Enqueue(dialog);
}
private static async void DisplayQueuedDialogs()
{
const int millisecondsBetweenDialogChecks = 500;
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
MessageDialog dialogToDisplay;
if (_dialogQueue.TryDequeue(out dialogToDisplay))
{
await dialogToDisplay.ShowAsync();
}
else
{
await Task.Delay(millisecondsBetweenDialogChecks);
}
}
}
}
This has changed my try/catch statement to
MessageDialog errorDialog = null;
try
{
await DoSomething();
}
catch(InvalidOperation ex)
{
MessageDialogDisplayer.DisplayDialog(new MessageDialog(ex.Message));
}
catch(CommunicationException)
{
MessageDialogDisplayer.DisplayDialog(new MessageDialog(StringResourceLoader.LoginError));
}
Which makes things more stable in the long run (once I convert all message dialog callers to use this instead of showAsyncing
themselves) and makes the try/catch block a lot less messy (imo).