如何使用 QEventLoop 同步等待多个 QNetwork 回复?
How to wait for multiple QNetwork replies synchronously using QEventLoop?
我的函数使用 QNetworkAccessManager 同时下载多个文件。然后它应该等待所有 QNetworkReply 回复完成,然后再继续其余代码。
但是我无法让 QEventLoop 与多个连接一起工作,它要么 returns 在所有回复完成之前,要么只是陷入我认为是无限循环的状态。
这是我的代码:
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
}
同样,我的目标是同时下载多个文件,并等待所有文件完成,然后再继续其余代码。
您可以使用计数器来检查信号被触发的次数。
#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://whosebug.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://whosebug.com/")
has error? false
===============================
Completed
我的函数使用 QNetworkAccessManager 同时下载多个文件。然后它应该等待所有 QNetworkReply 回复完成,然后再继续其余代码。
但是我无法让 QEventLoop 与多个连接一起工作,它要么 returns 在所有回复完成之前,要么只是陷入我认为是无限循环的状态。
这是我的代码:
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
}
同样,我的目标是同时下载多个文件,并等待所有文件完成,然后再继续其余代码。
您可以使用计数器来检查信号被触发的次数。
#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://whosebug.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://whosebug.com/")
has error? false
===============================
Completed