简体   繁体   English

如何使用 QEventLoop 同步等待多个 QNetwork 回复?

[英]How to wait for multiple QNetwork replies synchronously using QEventLoop?

My function downloads multiple files concurrently, using QNetworkAccessManager.我的函数使用 QNetworkAccessManager 同时下载多个文件。 And then it should wait for all the QNetworkReply replies to finish before continuing with the rest of the code.然后它应该等待所有 QNetworkReply 回复完成,然后再继续执行其余代码。

However I can't get QEventLoop to work with multiple connections, it either returns before all the replies finish, or just gets stuck in what I assume is an infinite loop.但是,我无法让 QEventLoop 处理多个连接,它要么在所有回复完成之前返回,要么陷入我认为是无限循环的困境。

This is my code:这是我的代码:

void DownloadFiles(QStringList urls)
{
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    QEventLoop loop;
    QNetworkReply *replies[6];

    for (int i = 0, i < urls.lenght(); i++){
        replies[i] = manager->get(QNetworkRequest(QUrl(urls[i]));
        connect(replies[i], SIGNAL(finished()), &loop, SLOT(quit()));
    }
    loop.exec();  // Wait here
    // Rest of code
}

Another attempt, perhaps even more nonsensical:另一种尝试,也许更荒谬:

void DownloadFiles(QStringList urls)
{
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    QEventLoop loops[6];
    QNetworkReply *replies[6];

    for (int i = 0, i < urls.lenght(); i++){
        replies[i] = manager->get(QNetworkRequest(QUrl(urls[i]));
        connect(replies[i], SIGNAL(finished()), &loops[i], SLOT(quit()));
    }
    for (int i = 0; i < 6; i++)
       loops[i]->exec();  // Wait here
    // Rest of code
}

Again, my goal is to download multiple file concurrently, and wait for all of them to finish before continuing with the rest of the code.同样,我的目标是同时下载多个文件,并在继续执行其余代码之前等待所有文件完成。

You can use a counter to check how many times the signal was triggered.您可以使用计数器来检查信号被触发的次数。

#include <QtNetwork>

static void DownloadFiles(const QList<QUrl> & urls){
    QNetworkAccessManager manager;
    QList<QNetworkReply *> replies;
    QEventLoop loop;
    int total = urls.length();
    for(const QUrl & url: urls){
        QNetworkReply *reply = manager.get(QNetworkRequest(url));
        QObject::connect(reply, &QNetworkReply::finished, [&total, &loop](){
            total--;
            if(total == 0){
                loop.quit();
            }
        });
        replies << reply;
    }
    loop.exec();
    for(QNetworkReply *reply: replies){
        qDebug() << "===============================";
        qDebug() << "url:" << reply->url() << "\nhas error?" << (reply->error() != QNetworkReply::NoError);
        qDebug() << "===============================";
    }
    qDebug() << "Completed";
    qDeleteAll(replies.begin(), replies.end());
    replies.clear();
}

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

    QList<QUrl> urls { QUrl("https://www.qt.io/"),
                       QUrl("https://github.com/"),
                       QUrl("https://stackoverflow.com/") };
    DownloadFiles(urls);

    return 0;
}

output:输出:

===============================
url: QUrl("https://www.qt.io/") 
has error? false
===============================
===============================
url: QUrl("https://github.com/") 
has error? false
===============================
===============================
url: QUrl("https://stackoverflow.com/") 
has error? false
===============================
Completed

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

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