Better way to show error messages in async methods

async-await, c#, modal-dialog, try-catch, windows-runtime

Solution

C# 6 now supports `await` in `catch` and `finally`, so the code can be written the way I wanted it; a workaround is no longer needed.

Problem

The fact that we can't use the `await` keyword in `catch` blocks makes it quite awkward to show error messages from async methods in WinRT, since the `MessageDialog` API is asynchronous. Ideally I would like be able to write this: ``` private async Task DoSomethingAsync() { try { // Some code that can throw an exception ... } catch (Exception ex) { var dialog = new MessageDialog("Something went wrong!"); await dialog.ShowAsync(); } } ``` But instead I have to write it like this: ``` private async Task DoSomethingAsync() { bool error = false; try { // Some code that can throw an exception ... } catch (Exception ex) { error = true; } if (error) { var dialog = new MessageDialog("Something went wrong!"); await dialog.ShowAsync(); } } ``` All methods that need to do this have to follow a similar pattern, which I really don't like, because it reduces the code readability. Is there a better way to handle this? EDIT: I came up with this (which is similar to what svick suggested in his comments): ``` static class Async { public static async Task Try(Func<Task> asyncAction) { await asyncAction(); } public static async Task Catch<TException>(this Task task, Func<TException, Task> handleExceptionAsync, bool rethrow = false) where TException : Exception { TException exception = null; try { await task; } catch (TException ex) { exception = ex; } if (exception != null) { await handleExceptionAsync(exception); if (rethrow) ExceptionDispatchInfo.Capture(exception).Throw(); } } } ``` Usage: ``` private async Task DoSomethingAsync() { await Async.Try(async () => { // Some code that can throw an exception ... }) .Catch<Exception>(async ex => { var dialog = new MessageDialog("Something went wrong!"); await dialog.ShowAsync(); }); } ``` `.Catch<...>` calls can be chained to mimick multiple `catch` blocks. But I'm not really happy with this solution; the syntax is even more awkward than before...

Original source