C++Winrt 如何在不终止程序的情况下抛出和处理异常

C++Winrt how to throw and handle exception without terminating program

我有以下代码

IAsyncOperation<bool> trythiswork()
    {
        bool contentFound{ false };
        try
        {
            auto result = co_await someAsyncFunc();
            winrt::check_bool(result)
            if (result)
            {
                contentFound = true;
            }
        }
        catch (...)
        {
            LOG_CAUGHT_EXCEPTION();
        }
        co_return contentFound;
    }

当结果为 false 时,它​​会失败并抛出异常,但 catch 会很快失败并终止程序。日志函数如何终止程序?它不应该只记录异常吗?我假设我正在处理这个异常,所以程序不会崩溃,但它正在崩溃。 那么如何抛出和捕获以使程序不终止呢?真想扔并且还捕获并最好记录异常。 谢谢

可以使用以下代码重现该问题:

IAsyncOperation<bool> someAsyncFunc() { co_return false; }

IAsyncOperation<bool> trythiswork()
{
    auto contentFound { false };
    try
    {
        auto result = co_await someAsyncFunc();
        winrt::check_bool(result);
        // throw std::bad_alloc {};
        contentFound = true;
    }
    catch (...)
    {
        LOG_CAUGHT_EXCEPTION();
    }
    co_return contentFound;
}

int main()
{
    init_apartment();
    auto result = trythiswork().get();
}

事实证明,一切都像宣传的那样工作,即使不是预期的那样。当 运行 附加调试器的代码时,您将看到以下调试输出:

The exception %s (0x [trythiswork]

不是很有帮助,但它表明日志记录本身是有效的。接下来是类似

的内容

FailFast(1) tid(b230) 8007023E {Application Error}

导致进程终止。 WIL 仅识别 std::exceptionwil::ResultExceptionPlatform::Exception^ 类型的异常。当它处理无法识别的异常类型时,它会默认终止进程。这可以通过注释掉对 check_bool 的调用并抛出标准异常(例如 std::bad_alloc)来验证。这会生成一个程序,该程序将记录异常详细信息,但会继续执行。

可以通过为 custom exception types 注册回调来自定义行为,让客户端控制自定义异常类型和 HRESULT 值之间的转换。这在 WIL 需要与使用其自身异常类型的外部库代码进行互操作的情况下非常有用。

对于 C++/WinRT 异常类型(基于 hresult_error) the WIL already provides error handling helpers that can be enabled (see Integrating with C++/WinRT)。要选择加入此选项,您需要做的就是在 any C++/WinRT headers 之前 #include <wil/cppwinrt.h>。当使用预编译的 headers 时,#include 指令应该去的地方。

通过该更改,该程序现在可以按预期运行:它记录源自 C++/WinRT 的异常的异常信息,并在处理异常后继续执行。