在异步方法中显示错误消息的更好方法 [英] Better way to show error messages in async methods

查看:28
本文介绍了在异步方法中显示错误消息的更好方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

但我必须这样写:

    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?

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

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

用法:

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<...> 调用可以链接起来以模仿多个 catch 块.

.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...

推荐答案

C# 6 现在支持 catchfinally 中的 await,所以代码可以按照我想要的方式编写;不再需要解决方法.

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.

这篇关于在异步方法中显示错误消息的更好方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆