由于捕获到异常,显示WinRT MessageDialog的正确方式是什么
本文关键字:方式 是什么 MessageDialog WinRT 于捕获 异常 显示 | 更新日期: 2023-09-27 18:24:38
由于捕获到异常,显示消息对话框的正确方式是什么?
我最初尝试
try
{
await DoSomething();
}
catch(InvalidOperation ex)
{
await MessageDialog(ex.Message).ShowAsync();
}
catch(CommunicationException)
{
await MessageDialog(StringResourceLoader.LoginError).ShowAsync();
}
这不起作用,因为您不能在try块内await
。去掉等待命令会使编译器显示以下警告:
因为不等待此调用,所以在调用完成之前继续执行当前方法。考虑将"等待"运算符应用于呼叫的结果
我不喜欢在代码中保留这些警告,因为在某些地方,人们忘记了使用await
,因此很难找到错误。
将消息对话框语句更改为var task = new MessageDialog(ex.Message).ShowAsync().AsTask();
可以消除所有警告和错误,但我不确定这是一个好的方法(从技术上讲,这是不好的,因为它希望我await
调用)
最后,我尝试存储异常,并在catch之外执行向用户显示什么的逻辑(包括确定抛出了什么类型的异常的所有逻辑),通过:
Exception thrownException = null;
try
{
await DoSomething();
}
catch(Exception ex)
{
thrownException = ex;
}
if (thrownException is InvalidOperationException)
await MessageDialog(ex.Message).ShowAsync();
else if (thrownException is CommunicationException)
await MessageDialog(StringResourceLoader.LoginError).ShowAsync();
我也不确定我是否觉得这是最好的方法。有什么想法吗?
编辑:在Hans对其他问题发表评论后,我最终通过创建以下类来解决它:
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)。