以下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();
第二个代码片段。挂起关闭()。
// 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();
}
第三个代码片段。挂起关闭()。
// 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();
}
}
Forth代码片段。挂在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();
答案 0 :(得分:2)
这些示例中的每个示例的问题看起来都是相同的:请求对象的错误构造和销毁。我做错了很少见到这样的聪明才智。
简单的解决方案是:
在调用close()之前,它似乎需要被销毁,这是合理的。
我的意思是第二个例子是唯一一个没有销毁对象的例子,它也失败了。我认为这是出于其他原因在此代码中不可见。
答案 1 :(得分:1)
免责声明:如果对该库没有任何了解,这是相当危险的
#include <iostream>
using namespace std;
class Obj {
public:
Obj() {
cout << "Constructor" << endl;
}
~Obj() {
cout << "Destructor" << endl;
}
};
int main() {
{
Obj ea;
ea.~Obj();
}
return 0;
}
输出:
Constructor
Destructor
Destructor
如果有资源被释放或要执行操作来清理请求,除非您执行以下步骤,否则在每种情况下都会造成很多麻烦:
pop
或try_pop
)在上面的片段中: