On Windows 8, a call to “await aMessageDialog.ShowAsync()” can only be made once, otherwise System.UnauthorizedAccessException will be thrown (E_ACCESSDENIED 80070005). This is a helper method to display dialogs although it’s not thread-safe. It’s inspired on StackOverflow answers:
public static class DialogDisplayer {
private static IAsyncOperation currentlyShownDialog;
public static async Task TryToShowDialog(MessageDialog messageDialog){
try{
RequestPreviousDialogCancelation();
await WaitForUIThreadToBeReady();
await ShowDialog(messageDialog);
}
catch (TimeoutException ex){
//Logger.Information("Time out waiting for a MessageDialog to be closed");
}
catch (TaskCanceledException ex){
CancelDialog();
}
catch (UnauthorizedAccessException ex){
//Logger.Information("Multiple dialogs are being opened at the same time. There is a direct call to ShowAsync somewhere. Instead of using ShowAsync, use this method");
}
}
private static void CancelDialog(){
currentlyShownDialog = null;
}
private static void RequestPreviousDialogCancelation(){
if (IsThereAnyOpenedDialog()){
currentlyShownDialog.Cancel();
}
}
private static async Task ShowDialog(MessageDialog messageDialog){
currentlyShownDialog = messageDialog.ShowAsync();
await currentlyShownDialog;
}
private static async Task WaitForUIThreadToBeReady(){
var attempts = 0;
while (IsThereAnyOpenedDialog()){
await Task.Delay(TimeSpan.FromMilliseconds(100));
attempts++;
if (attempts > 5){
throw new TimeoutException();
}
}
}
private static bool IsThereAnyOpenedDialog(){
return currentlyShownDialog != null && currentlyShownDialog.Status == AsyncStatus.Started;
}
}
Usage:
var messageDialog = new MessageDialog("Hello world");
await DialogDisplayer.TryToShowDialog(messageDialog);