以下 C++ 代码片段使用 Microsoft 的 C++ Rest SDK。我不明白为什么第一个片段有效而其他片段无效。我假设差异是由于对象破坏和范围规则造成的。我正在寻找关于为什么第一个片段有效而其他片段挂在 close() 上的解释。此外,SDK 可以做些什么来消除未来的错误。一些非常聪明的人看了片段,但从来没有看到问题。
第一个代码片段。该片段有效并完整显示。随后的代码片段替换其中的标记代码。请关注差异而不是其他干扰。通过在浏览器中发出单个 GET 请求并单步执行代码来测试代码。在所有情况下, request.reply() 只执行一次。
boost::lockfree::spsc_queue<web::http::http_request, boost::lockfree::capacity<1024>> queue;
web::http::experimental::listener::http_listener listener(U("http://localhost:3901"));
listener.support([&](web::http::http_request request)
{
queue.push(request);
});
listener.open().wait();
std::cout << "listening ... hit enter to initiate shutdown." << std::endl;
std::getchar();
// BEGIN CODE IN QUESTION
while (!queue.empty())
{
web::http::http_request request;
if (queue.pop(request))
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
}
// END CODE IN QUESTION
listener.close().wait();
第二个代码片段。挂在 close() 上。
// hangs on close().wait()
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
}
第三个代码片段。挂在 close() 上。
// hangs on close().wait(). Outer braces make no difference.
{
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
request.~http_request();
}
}
第四代码片段。挂在 close() 上。外大括号没有区别。
// hangs on close().wait()
{
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
request.~http_request();
}
request.~http_request();
}
更新:支持 Matt McNabb 的解释,如果我只发出一个 GET,则以下代码有效。我只是删除了循环来处理单个 GET。为了避免挂起,需要显式调用析构函数,但这是不正确的做法。
web::http::http_request request;
requests.pop(request);
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
request.~http_request();
更新:循环后的显式析构函数调用使程序为单个 GET 工作。但是,两个或更多 GET 会引发异常。我不确定为什么。
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
}
request.~http_request();