[Solved] QNetworkReply working in a hidden thread?
-
Hello,
I would like to know whether Qt manages networking on a hidden thread or the current thread?
void MyClass::getRequest(const QString url)
{
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileDownloaded(QNetworkReply*)));
request.setUrl(QUrl(url));
networkReply = manager.get(request);
connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(progress(qint64,qint64)));
finished = false;
while(!finished)
{
QApplication::processEvents();
qDebug() << "\nGoing to Sleep\n";
ThreadSleep::mySleep(QThread::currentThread(), 50);//sleeps the current thread for 50ms
}
}void MyClass::fileDownloaded(QNetworkReply *reply)
{
if(reply->error())
{
errorMessage = reply->errorString();
qDebug() << errorMessage << endl;
}
else
{
*data = reply->readAll();
qDebug() << *data;
}reply->deleteLater(); disconnect(&manager, 0, 0, 0); finished = true;
}
void MyClass::progress(qint64 done, qint64 total)
{
qDebug() << "\ndone " << done << "\ntotal " << total << endl;
}The output I am getting is this:
Going to SleepGoing to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 2078
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 11598
total 325954Going to Sleep
Going to Sleep
Going to Sleep
done 33358
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 46958
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 78238
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 87758
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 98638
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 127198
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 135358
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 142158
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 150318
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 161198
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 178878
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 200638
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 201998
total 325954Going to Sleep
Going to Sleep
done 214238
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 221038
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 233278
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 246878
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 259118
total 325954Going to Sleep
Going to Sleep
done 268638
total 325954Going to Sleep
Going to Sleep
done 271358
total 325954Going to Sleep
Going to Sleep
done 282238
total 325954Going to Sleep
Going to Sleep
Going to Sleep
done 287678
total 325954Going to Sleep
Going to Sleep
Going to Sleep
Going to Sleep
done 303998
total 325954Going to Sleep
Going to Sleep
done 314878
total 325954Going to Sleep
Going to Sleep
done 320318
total 325954Going to Sleep
done 325954
total 325954I have two questions:
- Is my downloading of data hampered due to the sleeping of my current thread?
- With what frequency is the downloadProgress() SIGNAL emitted and is there any impact due to sleeping?
-
By design QNetworkAccessManager is asynchronous i.e. the actual request is processed in a background thread.
So to answer your questions:
- No, the download is done on another thread. Your main thread can sleep, although I would consider
while(!finished)
a bad idea. The whole point of asynchronous call is not to block the main thread and you're doing it manually. I would recommend sending the request and connect slots that manage progress and finish and letting the code get back to the main event loop. Sleeping in the main thread results in UI freeze (if you have any UI). - That is an implementation detail and you should not rely or anticipate it. As far as you're concerned it can come after every byte or once for the whole download. It will depend on many aspects such as network throughput, protocol used, network card driver etc. Don't depend on it, just react to it. The impact is that if you receive a couple of these while you sleep they will be handled when your thread wakes up. It does not impact the download speed but it can cause the signals to stack up in the main thread, meaning you could get a lagged progress value every processEvent and then a bunch of them after the download is completed. This is another reason not to sleep in the main thread.
- No, the download is done on another thread. Your main thread can sleep, although I would consider
-
Hello Chris,
Thanks as always for your helpful answer!
Just wanted to let you know that the current thread not my GUI thread.
I am running it on a different thread, and anyway even if it were the GUI thread, wouldn't there be no freezing because I am still processing all the events?
The information about downloadProgress() was very helpful! -
As stated in the docs processEvents called in a loop does not process all kinds of events, but in your case this might not matter indeed.
If you're spinning another thread just to start a request and then wait for it in the loop isn't it kinda pointless? It would be easier to just make the request from the main thread and connect appropriate signals. Of course if processing of the incoming data takes long it might be a good idea to do it in another thread like you did, but if it's just a file download then another thread is kinda overkill.
-
I have shown only a simplified version of my code.
Actually I have lots of networking happening serially and parallel.
I transferred all of this to a new thread so as to keep my GUI thread free.
Thanks for your advice!