由于捕获的异常而显示消息对话框的正确方法是什么?
我最初尝试过
try
{
await DoSomething();
}
catch(InvalidOperation ex)
{
await MessageDialog(ex.Message).ShowAsync();
}
catch(CommunicationException)
{
await MessageDialog(StringResourceLoader.LoginError).ShowAsync();
}
这不起作用,因为你不能在try块中await
。将await命令输出会使编译器显示以下警告:
由于未等待此调用,因此在完成调用之前会继续执行当前方法。考虑将'await'运算符应用于调用的结果
我不喜欢在我的代码中保留这些警告,因为在几个地方,人们忘记使用await
因此很难找到错误。
将消息对话框语句更改为var task = new MessageDialog(ex.Message).ShowAsync().AsTask();
可以消除所有警告和错误,但我不确定这是一个很好的方法(从技术上来说,这是因为它希望我{ {1}}来电)
最后,我尝试通过以下方式存储异常,并在捕获之外执行向用户显示的内容的逻辑(包括确定抛出什么类型的异常的所有逻辑):
await
我不确定我是否认为这是最好的方法。有什么想法应该怎么做?
答案 0 :(得分:4)
修改: 汉斯对其他问题的评论后,我最终通过创建以下类来解决它:
public static class MessageDialogDisplayer
{
private static readonly ConcurrentQueue<MessageDialog> _dialogQueue;
private static readonly CancellationTokenSource _cancellationTokenSource;
static MessageDialogDisplayer()
{
_dialogQueue = new ConcurrentQueue<MessageDialog>();
_cancellationTokenSource = new CancellationTokenSource();
new Task(DisplayQueuedDialogs, _cancellationTokenSource.Token).Start();
}
public static void DisplayDialog(MessageDialog dialog)
{
_dialogQueue.Enqueue(dialog);
}
private static async void DisplayQueuedDialogs()
{
const int millisecondsBetweenDialogChecks = 500;
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
MessageDialog dialogToDisplay;
if (_dialogQueue.TryDequeue(out dialogToDisplay))
{
await dialogToDisplay.ShowAsync();
}
else
{
await Task.Delay(millisecondsBetweenDialogChecks);
}
}
}
}
这已将我的try / catch语句更改为
MessageDialog errorDialog = null;
try
{
await DoSomething();
}
catch(InvalidOperation ex)
{
MessageDialogDisplayer.DisplayDialog(new MessageDialog(ex.Message));
}
catch(CommunicationException)
{
MessageDialogDisplayer.DisplayDialog(new MessageDialog(StringResourceLoader.LoginError));
}
从长远来看,这使得事情变得更加稳定(一旦我将所有消息对话框调用者转换为使用它而不是showAsyncing
),并使try / catch块变得更加混乱(imo)。