【问题标题】:How to wait for multiple QNetwork replies synchronously using QEventLoop?如何使用 QEventLoop 同步等待多个 QNetwork 回复?
【发布时间】:2020-03-29 21:26:20
【问题描述】:

我的函数使用 QNetworkAccessManager 同时下载多个文件。然后它应该等待所有 QNetworkReply 回复完成,然后再继续执行其余代码。

但是我不能让 QEventLoop 处理多个连接,它要么在所有回复完成之前返回,要么就陷入我认为是无限循环的状态。

这是我的代码:

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
}

另一个尝试,也许更荒谬:

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
}

同样,我的目标是同时下载多个文件,并等待所有文件都完成,然后再继续执行其余代码。

【问题讨论】:

    标签: c++ qt qtnetwork


    【解决方案1】:

    您可以使用计数器来检查信号被触发的次数。

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

    输出:

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

    【讨论】:

      猜你喜欢
      • 2014-02-20
      • 2021-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-15
      • 2018-06-17
      • 1970-01-01
      • 2020-05-12
      相关资源
      最近更新 更多