Melhor maneira de mostrar mensagens de erro em métodos assíncronos
O fato de não podermos usar oawait
palavra-chave emcatch
blocos torna bastante difícil mostrar mensagens de erro de métodos assíncronos no WinRT, uma vez que oMessageDialog
API é assíncrona. Idealmente, gostaria de poder escrever isto:
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();
}
}
Mas em vez disso eu tenho que escrever assim:
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();
}
}
Todos os métodos que precisam fazer isso têm que seguir um padrão similar, o que eu realmente não gosto, porque reduz a legibilidade do código.
Existe uma maneira melhor de lidar com isso?
EDITAR: Eu inventei isso (o que é similar ao que o svick sugeriu em seus comentários):
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();
}
}
}
Uso:
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<...>
chamadas podem ser encadeadas para imitar múltiploscatch
blocos.
Mas eu não estou muito feliz com essa solução; a sintaxe é ainda mais estranha do que antes ...