简体   繁体   English

QEventLoop 没有同步等待 QNetworkReply 完成

[英]QEventLoop not waiting synchronously for QNetworkReply to finish

I am building a library with Qt that calls a server and I need to build a synchronous function that waits for an HTTP response (QNetworkReply object) and I am using a QEventLoop to achieve this.我正在使用调用服务器的 Qt 构建一个库,我需要构建一个同步 function 来等待 HTTP 响应(QNetworkReply 对象),我正在使用 QNetworkReply 对象。 Currently the server gets called but the loop does not wait for the reply to finish, instead it carries on with an empty QNetworkReply object.当前服务器被调用,但循环不等待回复完成,而是继续使用空的 QNetworkReply object。

The exact same function works in a simple test project I built that only contains one thread and a call from main to this function.完全相同的 function 在我构建的一个简单测试项目中工作,该项目仅包含一个线程和从 main 到此 function 的调用。 The reply is waited for and everything works as expected.等待回复,一切都按预期工作。 But in my project that contains multiple threads the scenario described above occurs and the event loop does not wait for the reply.但是在我的包含多个线程的项目中,会发生上述场景并且事件循环不等待回复。 The request is sent to the server and shows up there but the response can't get back to the QNetworkReply object because the function has already executed.请求被发送到服务器并显示在那里,但响应无法返回到 QNetworkReply object,因为 function 已经执行。

Here is the network section of my function.这是我的function的网络部分。 In my project the statusCode variable always ends up being 0 and the reply is empty but in the simple test scenario they are 200 and the expected HTTP response.在我的项目中,statusCode 变量始终为 0 并且回复为空,但在简单的测试场景中,它们为 200 和预期的 HTTP 响应。

QNetworkAccessManager* networkManager = new QNetworkAccessManager(this);
QNetworkReply* reply = networkManager->get(request);

QEventLoop loop;
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();

QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
qInfo() << "Http Get completed with status code:" << statusCode.toInt();

Cause原因

Excuse me, I wasn't listening to you...对不起,我没听你的……

In other words, you connect to the finished signal after the request has been made, so no one is listening to your signal at the time the request has been made.换句话说,您在发出请求连接到finished的信号,因此在发出请求时没有人在监听您的信号。

Solution解决方案

Connect to QNetworkAccessManager::finished before you send the request with networkManager->get(request) .在使用networkManager->get(request)发送请求之前连接到QNetworkAccessManager::finished

Example例子

Please read carefully the detailed description of QNetworkAccessManager .请仔细阅读QNetworkAccessManager的详细描述。 There are examples of how to use the class properly.有如何正确使用 class 的示例。 Eg:例如:

QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished,
        this, &MyClass::replyFinished);

manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QUrl resource(url);
QNetworkRequest request(resource);
QNetworkReply *reply = manager->get(request);
QEventLoop loop;
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
QJsonObject jsonObject = QJsonDocument::fromJson(reply->readAll()).object();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM