Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Why QNetworkAccessManager::finished is fired on the main thread?

Why QNetworkAccessManager::finished is fired on the main thread?

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 4 Posters 839 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dmitriano
    wrote on last edited by Dmitriano
    #1

    I created a QThread with a code like this:

    void MyThread::run()
    {
        QEventLoop loop;
    
        QNetworkAccessManager nm;
    
        QObject::connect(&nm, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply)
        {
             //the lambda is called on the main thread
        }
    
        QNetworkRequest request;
        request.setUrl(QUrl("https://api.binance.com/api/v3/exchangeInfo"));
        nm.get(request);
        
        loop.exec();
    }
    

    and expected that the lambda is called on the thread nm object belongs to, but it is called on the main thread. why?

    JKSHJ 1 Reply Last reply
    0
    • D Dmitriano

      I created a QThread with a code like this:

      void MyThread::run()
      {
          QEventLoop loop;
      
          QNetworkAccessManager nm;
      
          QObject::connect(&nm, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply)
          {
               //the lambda is called on the main thread
          }
      
          QNetworkRequest request;
          request.setUrl(QUrl("https://api.binance.com/api/v3/exchangeInfo"));
          nm.get(request);
          
          loop.exec();
      }
      

      and expected that the lambda is called on the thread nm object belongs to, but it is called on the main thread. why?

      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #6

      @Dmitriano said in Why QNetworkAccessManager::finished is fired on the main thread?:

      and expected that the lambda is called on the thread nm object belongs to, but it is called on the main thread. why?

      Because this rule applies to all QObjects: A slot will execute in the thread that the QObject lives in. (See https://doc.qt.io/qt-5/qobject.html#thread-affinity )

      A QThread is a QObject that manages a secondary thread. However, your QThread object lives in the main thread. Therefore, its slots will execute in the main thread.

      QObject::connect(&nm, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply)
      {
          // This lambda runs in this->thread()
      }
      
      QObject::connect(&nm, &QNetworkAccessManager::finished, &nm, [=](QNetworkReply *reply)
      {
          // This lambda runs in nm.thread()
      }
      
      // To see which thread each object lives in, run this code:
      qDebug() << qApp->thread();
      qDebug() << this->thread();
      qDebug() << this;
      qDebug() << nm.thread();
      

      Note:

      • You don't need QEventLoop. Just call this->exec()
      • You don't even need a thread. QNetworkAccessManager is asynchronous -- you can run it in your main thread.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      Christian EhrlicherC 1 Reply Last reply
      3
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi,

        How are you using your MyThread class ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        D 1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          How are you using your MyThread class ?

          D Offline
          D Offline
          Dmitriano
          wrote on last edited by Dmitriano
          #3

          @SGaist I declare my thread class

              class MyThread : public QThread
              {
                  Q_OBJECT;
          
              protected:
          
                  void run() override;
              };
          

          then I declare its instance as a member of MyModel class derived from QAbstractListModel that is created in QML.

          in MyModel's constructor I call

          m_myThread.start();
          

          and when the app closes I call

          m_myThread.quit();
          m_myThread.wait();
          
          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #4

            How did you determine that the lambda was called in the main thread ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            D 1 Reply Last reply
            0
            • SGaistS SGaist

              How did you determine that the lambda was called in the main thread ?

              D Offline
              D Offline
              Dmitriano
              wrote on last edited by
              #5

              @SGaist I was able to debug my app, see the picture
              alt text

              1 Reply Last reply
              0
              • D Dmitriano

                I created a QThread with a code like this:

                void MyThread::run()
                {
                    QEventLoop loop;
                
                    QNetworkAccessManager nm;
                
                    QObject::connect(&nm, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply)
                    {
                         //the lambda is called on the main thread
                    }
                
                    QNetworkRequest request;
                    request.setUrl(QUrl("https://api.binance.com/api/v3/exchangeInfo"));
                    nm.get(request);
                    
                    loop.exec();
                }
                

                and expected that the lambda is called on the thread nm object belongs to, but it is called on the main thread. why?

                JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on last edited by
                #6

                @Dmitriano said in Why QNetworkAccessManager::finished is fired on the main thread?:

                and expected that the lambda is called on the thread nm object belongs to, but it is called on the main thread. why?

                Because this rule applies to all QObjects: A slot will execute in the thread that the QObject lives in. (See https://doc.qt.io/qt-5/qobject.html#thread-affinity )

                A QThread is a QObject that manages a secondary thread. However, your QThread object lives in the main thread. Therefore, its slots will execute in the main thread.

                QObject::connect(&nm, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply)
                {
                    // This lambda runs in this->thread()
                }
                
                QObject::connect(&nm, &QNetworkAccessManager::finished, &nm, [=](QNetworkReply *reply)
                {
                    // This lambda runs in nm.thread()
                }
                
                // To see which thread each object lives in, run this code:
                qDebug() << qApp->thread();
                qDebug() << this->thread();
                qDebug() << this;
                qDebug() << nm.thread();
                

                Note:

                • You don't need QEventLoop. Just call this->exec()
                • You don't even need a thread. QNetworkAccessManager is asynchronous -- you can run it in your main thread.

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                Christian EhrlicherC 1 Reply Last reply
                3
                • JKSHJ JKSH

                  @Dmitriano said in Why QNetworkAccessManager::finished is fired on the main thread?:

                  and expected that the lambda is called on the thread nm object belongs to, but it is called on the main thread. why?

                  Because this rule applies to all QObjects: A slot will execute in the thread that the QObject lives in. (See https://doc.qt.io/qt-5/qobject.html#thread-affinity )

                  A QThread is a QObject that manages a secondary thread. However, your QThread object lives in the main thread. Therefore, its slots will execute in the main thread.

                  QObject::connect(&nm, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply)
                  {
                      // This lambda runs in this->thread()
                  }
                  
                  QObject::connect(&nm, &QNetworkAccessManager::finished, &nm, [=](QNetworkReply *reply)
                  {
                      // This lambda runs in nm.thread()
                  }
                  
                  // To see which thread each object lives in, run this code:
                  qDebug() << qApp->thread();
                  qDebug() << this->thread();
                  qDebug() << this;
                  qDebug() << nm.thread();
                  

                  Note:

                  • You don't need QEventLoop. Just call this->exec()
                  • You don't even need a thread. QNetworkAccessManager is asynchronous -- you can run it in your main thread.
                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  One more note:

                  • Again a nice example on how to misuse lambdas

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved