QEventLoop ожидает только локальные события, а не события основного цикла - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь выполнить сетевой запрос и дождаться ответа, прежде чем двигаться дальше.В то время как использование QEventLoop работает для ожидания запроса, проблема заключается в том, что в других частях программы будут запущены другие сигналы, которые они будут выполнять первыми.

Вот пример кода, повторно создающего проблему.Вы можете видеть, что сетевой запрос (я использую http://example.com здесь только для примера) явно будет выдан до того, как сработает второй таймер singleShot.

#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();
}

Вотвывод: enter image description here

Вот требуемый вывод: enter image description here

Редактировать

Чтобы добавить больше информации.Приведенный выше код явно упрощает проблему, поскольку я не могу легко опубликовать весь код.В основном происходит то, что где-то в моем проекте есть код, который будет излучать сигнал, связанный с longFunction() выше.Очевидно, что я хочу дождаться ответа от вызова REST, прежде чем продолжить, потому что ответ будет диктовать элементы позже в этой функции.Проблема в том, что в какой-то момент позже (возможно, до завершения вызова REST) ​​некоторые другие части моего кода могут вызвать другой сигнал, и я не хочу, чтобы эти другие сигналы обрабатывались.Я просто хочу дождаться обработки ОДНОГО соединения на localEventLoop.

Любая помощь будет принята с благодарностью

1 Ответ

0 голосов
/ 14 февраля 2019
QTimer::singleShot(0, &longFunction);

- асинхронная функция.Возвращается до того, как void longFunction() выполнил QEventLoop.В результате ваш второй QTimer::singleShot(1, []() { сработает немедленно.Решение состоит в том, чтобы переместить QEventLoop за пределы вашей функции до QTimer::singleShot(1, []() {

...