首页 > 解决方案 > 在 C++/WinRT 中捕获 ContentDialog::ShowAsync 引发的异常

问题描述

在 C++/CX 我有:

IAsyncOperation<ContentDialogResult> Dialog::show() {
    return dialog_.ShowAsync();
}

如果我创建并尝试显示两个对话框,结果 show() 被调用两次,ShowAsync 曾经抛出异常:

任何时候都只能打开一个 ContentDialog

我过去常常抓住并处理这个案子。当我将此代码转换为 C++/WinRT 时,根据我对转换规则的理解,有:

IAsyncOperation<ContentDialogResult> Dialog::show() {
    co_return co_await dialog_.ShowAsync();
}

调用者看起来像这样:

void Dialog::caller(){
    .....
    try {
        show();
    } catch (winrt::hresult_error err) {
        handle.....
        return;
    }
    ......
    ......
}

我确实看到抛出了一个 Windows 异常,但不知何故它没有被我的代码捕获。

这是调用 ShowAsync() 的正确方法吗?我该如何处理这个异常?

标签: uwpuwp-xamlc++-cxc++-winrtcppwinrt

解决方案


一次只能显示一个 ContentDialog。

当您直接调用 show() 两次时,第二个对话框将在第一个对话框显示后立即尝试显示。它不会在显示前等待第一个对话框关闭,因此将引发此异常。

如果要一个一个显示两个对话框,则需要等待第一个对话框操作完成,然后再显示第二个。例如:

对于 C++/CX,您可以尝试使用任务类来使用异步操作。

IAsyncOperation<ContentDialogResult>^ ShowDialogSample::MainPage::Show()
{
    return dialog->ShowAsync();
}

void MainPage::CallerFunction()
{
    auto ShowTask = create_task(Show());
    ShowTask.then([this](ContentDialogResult result)
    {
        ...... 
        Show();
    });
}

对于 C++/WinRT,您可以使用 co_await 语句来协同等待函数的结果,然后继续下一步。

IAsyncOperation<ContentDialogResult> MainPage::Show()
{
    co_return co_await dialog.ShowAsync();
}

IAsyncAction MainPage::CallerFunction()
{      
    ......
    co_await Show();
    co_await Show();     
    ......
}

推荐阅读