C++/WinRT如何抛出并捕获异常避免程序意外终止
问题原因
- 你所用的
LOG_CAUGHT_EXCEPTION是Windows实现库(WIL)提供的日志宏,它的默认行为不止是记录异常:如果没有注册自定义日志回调函数,或者当前捕获的异常被判定为严重错误级别,宏内部会自动调用快速终止接口直接退出程序,并不会只完成日志记录逻辑。 - 额外注意你提供的示例代码存在语法问题:
winrt::check_bool(result)后缺少分号,编译阶段会报错,实际运行的代码应已补全该分号。
解决方案
你可以根据业务需求选择以下任意一种方案实现预期效果:
方案1:替换为非终止型日志逻辑
如果你不需要WIL提供的异常上下文自动上报能力,直接替换为自定义日志逻辑或者WIL的普通日志宏即可:
IAsyncOperation<bool> trythiswork() { bool contentFound{ false }; try { auto result = co_await someAsyncFunc(); winrt::check_bool(result); contentFound = result; } catch (const winrt::hresult_error& e) { // 自定义记录异常信息,比如输出错误码和消息 OutputDebugStringW(e.message().c_str()); // 也可以用WIL的非终止型日志宏,不会触发程序退出 LOG_INFO("捕获预期异常,错误码:0x%08X", e.code()); } catch (...) { // 捕获其他未知异常,仅做记录 LOG_INFO("捕获未知异常"); } co_return contentFound; }
方案2:注册WIL自定义日志回调
如果你需要保留WIL的日志能力,可在程序初始化阶段注册自定义日志处理回调,对预期内的异常屏蔽自动终止逻辑:
// 程序初始化阶段执行一次即可 WI_SetLoggingCallback([](DWORD severity, PCWSTR message, HRESULT hr, void* /*context*/) noexcept { // 自行实现日志记录逻辑,这里以输出调试信息为例 if (severity >= WIL_LOG_LEVEL_ERROR) { OutputDebugStringW(message); } // 对于check_bool抛出的E_BOOL错误,返回S_OK告知WIL不要触发终止 if (hr == E_BOOL) { return S_OK; } // 其他异常可根据业务需求判断是否需要终止 return S_OK; }, nullptr);
方案3:跳过异常抛出逻辑直接处理返回值
winrt::check_bool的作用就是在参数为false时抛出异常,如果你本身就需要处理false的场景,完全可以去掉异常抛出逻辑,直接判断返回值,代码更简洁也没有异常开销:
IAsyncOperation<bool> trythiswork() { bool contentFound{ false }; try { auto result = co_await someAsyncFunc(); contentFound = result; if (!result) { LOG_INFO("异步调用返回false,未找到对应内容"); } } catch (...) { LOG_INFO("捕获异步调用异常"); } co_return contentFound; }
内容的提问来源于stack exchange,提问作者rsp
相关产品推荐
相关产品推荐

