简体   繁体   中英

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. 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.

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. 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.

Here is the network section of my 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.

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.

Solution

Connect to QNetworkAccessManager::finished before you send the request with networkManager->get(request) .

Example

Please read carefully the detailed description of QNetworkAccessManager . There are examples of how to use the class properly. 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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