在异步方法中显示错误消息的更好方法

我们不能在catch块中使用await关键字这一事实使得在WinRT中显示来自异步方法的错误消息非常尴尬,因为MessageDialog API是异步的。 理想情况下,我希望能够写下这个:

  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(); } } 

但相反,我必须这样写:

  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(); } } 

所有需要这样做的方法必须遵循类似的模式,我真的不喜欢它,因为它降低了代码的可读性。

有没有更好的方法来处理这个?


编辑:我想出了这个(这与svick在他的评论中建议的类似):

 static class Async { public static async Task Try(Func asyncAction) { await asyncAction(); } public static async Task Catch(this Task task, Func 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(); } } } 

用法:

 private async Task DoSomethingAsync() { await Async.Try(async () => { // Some code that can throw an exception ... }) .Catch(async ex => { var dialog = new MessageDialog("Something went wrong!"); await dialog.ShowAsync(); }); } 

.Catch调用可以链接到模仿多个catch块。

但我对这个解决方案并不满意; 语法比以前更尴尬……

您已经在TPL中拥有该function

  await Task.Run(async () => { // Some code that can throw an exception ... }).ContinueWith(async (a) => { if (a.IsFaulted) { var dialog = new MessageDialog("Something went wrong!\nError: " + a.Exception.Message); await dialog.ShowAsync(); } else { var dialog2 = new MessageDialog("Everything is OK: " + a.Result); await dialog2.ShowAsync(); } }).Unwrap(); 

在这台机器上我没有Windows 8,所以我在Windows 7中进行了测试,但我认为是相同的。 *按照所需的评论中的说明进行编辑.Unwrap(); 最终等待工作

C#6现在支持在catch awaitfinally ,代码可以按我想要的方式编写; 不再需要解决方法。