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

Tho*_*que 12 c# modal-dialog try-catch async-await windows-runtime

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

    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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

但相反,我必须这样写:

    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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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


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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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();
    });
}
Run Code Online (Sandbox Code Playgroud)

.Catch<...>可以将调用链接到模仿多个catch块.

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

Tho*_*que 0

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