使用cpprest发送无需等待响应的异步HTTP请求及异常处理
解决cpprest异步HTTP请求未处理异常导致崩溃的问题
你的问题核心是:cpprest的异步task如果存在未被观察到的异常,当task的最后一个引用被销毁时,会触发程序崩溃。原代码只处理了响应回调中的异常,但**请求发送阶段的异常(如网络错误、请求构造失败)**没有被捕获,这些异常会留在task中,当触发线程结束后,task的析构函数会检测到未观察的异常,从而抛出你看到的_ExceptionHolder错误。
解决方案:捕获所有task链中的异常
因为你不关心请求结果,只需确保所有可能的异常都被处理,避免未观察异常即可。以下是两种可靠的实现方式:
方式1:通过task参数捕获所有异常
直接在后续的then中接收前一个task对象,调用get()并捕获所有异常:
client.request(request) .then([](pplx::task<web::http::http_response> task) { try { // 尝试获取响应,这里会抛出请求阶段的异常 auto response = task.get(); // 不关心响应结果,直接忽略 (void)response; } catch (const std::exception& e) { // 忽略所有异常,也可按需记录日志 (void)e; } });
方式2:使用catch延续捕获异常
利用cpprest的catch方法直接捕获整个task链中的异常:
client.request(request) .then([](web::http::http_response response) { // 忽略响应结果 (void)response; }) .catch([](const std::exception& e) { // 捕获所有异常并忽略 (void)e; });
关键说明
- 不需要调用
wait():调用wait()会阻塞当前线程,违背你“无需等待响应”的需求。cpprest的task会由内部线程池管理,即使触发线程结束,task仍会在后台执行,异常被捕获后不会影响主程序。 - 必须覆盖所有异常场景:请求发送阶段(如DNS解析失败、连接超时)和响应处理阶段的异常都要被捕获,否则仍会触发未观察异常崩溃。
内容的提问来源于stack exchange,提问作者InUser
相关产品推荐
相关产品推荐

