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

    Going to Sleep

    done 2078
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 11598
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 33358
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 46958
    total 325954

    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 78238
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 87758
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 98638
    total 325954

    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 127198
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 135358
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 142158
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 150318
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 161198
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 178878
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 200638
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 201998
    total 325954

    Going to Sleep

    Going to Sleep

    done 214238
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 221038
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 233278
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 246878
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 259118
    total 325954

    Going to Sleep

    Going to Sleep

    done 268638
    total 325954

    Going to Sleep

    Going to Sleep

    done 271358
    total 325954

    Going to Sleep

    Going to Sleep

    done 282238
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 287678
    total 325954

    Going to Sleep

    Going to Sleep

    Going to Sleep

    Going to Sleep

    done 303998
    total 325954

    Going to Sleep

    Going to Sleep

    done 314878
    total 325954

    Going to Sleep

    Going to Sleep

    done 320318
    total 325954

    Going to Sleep

    done 325954
    total 325954

    I have two questions:

    1. Is my downloading of data hampered due to the sleeping of my current thread?
    2. With what frequency is the downloadProgress() SIGNAL emitted and is there any impact due to sleeping?

  • Moderators

    By design QNetworkAccessManager is asynchronous i.e. the actual request is processed in a background thread.

    So to answer your questions:

    1. 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).
    2. 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.


  • 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!


  • Moderators

    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!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.