What is the correct way to show WinRT MessageDialog due to a caught exception?

What is the correct way to show a message dialog due to a caught exception?

I originally tried

try { await DoSomething(); } catch(InvalidOperation ex) { await MessageDialog(ex.Message).ShowAsync(); } catch(CommunicationException) { await MessageDialog(StringResourceLoader.LoginError).ShowAsync(); } 

This did not work because you cannot await inside the try block. Accepting wait commands, the compiler displays the following warning:

Since this call is not expected, execution of the current method continues until the call is completed. Consider applying the wait statement to a call result

I do not like these warnings in my code because in several places people forgot to use await and therefore it is difficult to find errors.

Change the message dialog operator to var task = new MessageDialog(ex.Message).ShowAsync().AsTask(); eliminates all warnings and errors, but I'm not sure if this is a good way to do this (and technically this is bad for the same reason that he wants me to await call)

Finally, I tried to save the exception and make my logic of what to show the user (including the entire logic of determining what type of exception was thrown) outside of catch, by:

 Exception thrownException = null; try { await DoSomething(); } catch(Exception ex) { thrownException = ex; } if (thrownException is InvalidOperationException) await MessageDialog(ex.Message).ShowAsync(); else if (thrownException is CommunicationException) await MessageDialog(StringResourceLoader.LoginError).ShowAsync(); 

I'm not sure I feel that this is the best way to do this. Any ideas how to do this?

+4
source share
1 answer

Edit: After Hans comments on other issues, I decided to solve this 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 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 (as soon as I convert all the calling dialogs to use this instead of showAsyncing ) and makes the try / catch block much less messy (imo).

+4
source

Source: https://habr.com/ru/post/1493023/


All Articles