0

I'm trying to execute a network request and wait for the response before moving on. Whereas using a QEventLoop works to wait for the request, the problem is if there are other signals fired in other parts of the program they will execute first.

Here is an example of the code re-producing the problem. You can see the network request (I'm using http://example.com here just for example) is clearly going to be issued before the second singleShot timer will fire.

#include <QApplication>
#include <QTimer>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>

void longFunction()
{
    qDebug() << "Starting Long Function";
    QEventLoop localEventLoop;
    QNetworkAccessManager manager;
    QNetworkReply *reply = manager.get(QNetworkRequest(QUrl("http://example.com")));
    QObject::connect(reply, &QNetworkReply::finished, &localEventLoop, &QEventLoop::quit);

    // I wish to block here
    //    - do not want to pass this point and run
    //      other events if fired from the main event loop
    localEventLoop.exec();

    qDebug() << "Finishing Long Function";
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTimer::singleShot(0, &longFunction);
    QTimer::singleShot(1, []() {
        qDebug() << "  -- Some other function that was issued after";
        qDebug() << "  -- 'longFunction' started but before 'longFunction' ended";
    });

    return a.exec();
}

Here is the output: enter image description here

Here is the desired output: enter image description here

Edit

To add some more info. The code above is obviously an over simplification of the problem as I can't easily post all of the code. Basically whats happening is there is code somewhere else in my project that will emit a signal that is connected to the longFunction() above. Obviously I want to wait for a response from the REST call before continuing because the response will dictate the elements later in that function. The issue is that at some point later (potentially before the REST call finishes), some other parts of my code might trigger some other signal and I don't want those other signals to be processed. I just want to wait for the ONE connection on the localEventLoop to be processed.

Any help would be greatly appreciated

Stanton
  • 904
  • 10
  • 25

1 Answers1

0
QTimer::singleShot(0, &longFunction);

is an asynchronous function. It returns before void longFunction() executed the QEventLoop. The result is that your second QTimer::singleShot(1, []() { will trigger immediately. The solution is to move QEventLoop outside your function, before QTimer::singleShot(1, []() {

user3606329
  • 2,405
  • 1
  • 16
  • 28