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

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

问题描述

这是我们不能在捕捉使用等待关键字事实块使得它非常尴尬,显示错误在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();
        }
    }

而是我必须把它写这样的:

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

这需要做到这一点的所有方法都遵循类似的模式,我真的不喜欢,因为它降低了code可读性。

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&LT; ...&GT; 呼叫可以被链接致力于模拟多个

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

推荐答案

您已经在TPL该功能

        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()表示;到底为的await工作

In this machine I don't have Windows 8 so I tested in Windows 7 but I think is the same. *Edit as stated in the comments its needed .Unwrap(); in the end for the await to work

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

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