由于捕获的异常,显示WinRT MessageDialog的正确方法是什么?

时间:2013-07-23 17:38:08

标签: c# windows-runtime

由于捕获的异常而显示消息对话框的正确方法是什么?

我最初尝试过

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

我不确定我是否认为这是最好的方法。有什么想法应该怎么做?

1 个答案:

答案 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)。