我们不能在 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 现在支持 catch
和 finally
中的 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.
这篇关于在异步方法中显示错误消息的更好方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!