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 QtConcurrent::run freezing my program?
Qt 6.11 is out! See what's new in the release blog

Why QtConcurrent::run freezing my program?

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 1.9k Views
  • 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.
  • I Offline
    I Offline
    isan
    wrote on last edited by isan
    #1

    I read QString from the database which has a lot of data
    I want to split QString line by line and then use it,
    When I use the for to split it, my app freezes and doesn't work,
    I found that the run function QtConcurrent :: run a function in a separate thread
    I did as below, but my application still freeze when calling function readfile

    void MainWindow::getData(){
     QString getRecord=dbFile->getRecord(IdGet);
    
        QFuture<void> t1 = QtConcurrent::run(demoSimple,&ZoomScrollTrack2::readfile, getRecord);
    
        t1.waitForFinished();
    }
    
    void Track::readfile(QString Record){
    
    
        for(int u=0;u<Record.size();u++){
            QStringList line=Record.split("#");
             qDebug()<<"record list"<<line;
    
    }
    }
    

    I try to use this way but I have error (no matching function for call to run)

    QFuture<QList<QString>> future = QtConcurrent::run(IdGet, &QString::split, '#');
       QList<QString> result = future.result();
        qDebug()<<"list"<<result;
    

    Is QtConcurrent::run function is a good way for my action or I need to use QThread with subclass?

    J.HilkJ KroMignonK 2 Replies Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by Christian Ehrlicher
      #2

      Since you're directly waiting for the result your gui freezes. You should connect to the QFuture signals and/or use QFutureWatcher. See https://doc.qt.io/qt-5/qtconcurrent-index.html

      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
      3
      • I isan

        I read QString from the database which has a lot of data
        I want to split QString line by line and then use it,
        When I use the for to split it, my app freezes and doesn't work,
        I found that the run function QtConcurrent :: run a function in a separate thread
        I did as below, but my application still freeze when calling function readfile

        void MainWindow::getData(){
         QString getRecord=dbFile->getRecord(IdGet);
        
            QFuture<void> t1 = QtConcurrent::run(demoSimple,&ZoomScrollTrack2::readfile, getRecord);
        
            t1.waitForFinished();
        }
        
        void Track::readfile(QString Record){
        
        
            for(int u=0;u<Record.size();u++){
                QStringList line=Record.split("#");
                 qDebug()<<"record list"<<line;
        
        }
        }
        

        I try to use this way but I have error (no matching function for call to run)

        QFuture<QList<QString>> future = QtConcurrent::run(IdGet, &QString::split, '#');
           QList<QString> result = future.result();
            qDebug()<<"list"<<result;
        

        Is QtConcurrent::run function is a good way for my action or I need to use QThread with subclass?

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #3

        @isan additional to what @Christian-Ehrlicher said, you may want to consider using splitRef('#') it returns a QVector<QStringRef> instead of a QList<QString> it is significantly faster, but it depends on the lifetime of the original QString!


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        4
        • I isan

          I read QString from the database which has a lot of data
          I want to split QString line by line and then use it,
          When I use the for to split it, my app freezes and doesn't work,
          I found that the run function QtConcurrent :: run a function in a separate thread
          I did as below, but my application still freeze when calling function readfile

          void MainWindow::getData(){
           QString getRecord=dbFile->getRecord(IdGet);
          
              QFuture<void> t1 = QtConcurrent::run(demoSimple,&ZoomScrollTrack2::readfile, getRecord);
          
              t1.waitForFinished();
          }
          
          void Track::readfile(QString Record){
          
          
              for(int u=0;u<Record.size();u++){
                  QStringList line=Record.split("#");
                   qDebug()<<"record list"<<line;
          
          }
          }
          

          I try to use this way but I have error (no matching function for call to run)

          QFuture<QList<QString>> future = QtConcurrent::run(IdGet, &QString::split, '#');
             QList<QString> result = future.result();
              qDebug()<<"list"<<result;
          

          Is QtConcurrent::run function is a good way for my action or I need to use QThread with subclass?

          KroMignonK Offline
          KroMignonK Offline
          KroMignon
          wrote on last edited by KroMignon
          #4

          @isan You need to use QFutureWatcher in combination with QEventLoop to not lock you main thread.
          Something like this:

          // start process in another thread
          QFuture<void> future = QtConcurrent::run(demoSimple,&ZoomScrollTrack2::readfile, getRecord));
          
          QFutureWatcher<void> watcher;
          QEventLoop loop;
          // QueuedConnection is necessary in case the signal finished is emitted before the loop starts
          // (if the task is already finished when setFuture is called)
          connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()),  Qt::QueuedConnection); 
          watcher.setFuture(future);
          qDebug()<<"wait for result";
          
          // passive wait until QFuture is finished
          loop.exec();
          qDebug()<<"done";
          

          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

          Christian EhrlicherC 1 Reply Last reply
          1
          • I Offline
            I Offline
            isan
            wrote on last edited by
            #5

            Thanks for your help
            It works, but it takes a few minutes, is there a better way to make it faster?

            J.HilkJ 1 Reply Last reply
            0
            • I isan

              Thanks for your help
              It works, but it takes a few minutes, is there a better way to make it faster?

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by
              #6

              @isan compiling and running it in release mode will make it a good bit faster.

              besides that, truncating your QString beforehand and running multiple QtConcurrent each one with part of the original string?


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              1 Reply Last reply
              1
              • KroMignonK KroMignon

                @isan You need to use QFutureWatcher in combination with QEventLoop to not lock you main thread.
                Something like this:

                // start process in another thread
                QFuture<void> future = QtConcurrent::run(demoSimple,&ZoomScrollTrack2::readfile, getRecord));
                
                QFutureWatcher<void> watcher;
                QEventLoop loop;
                // QueuedConnection is necessary in case the signal finished is emitted before the loop starts
                // (if the task is already finished when setFuture is called)
                connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()),  Qt::QueuedConnection); 
                watcher.setFuture(future);
                qDebug()<<"wait for result";
                
                // passive wait until QFuture is finished
                loop.exec();
                qDebug()<<"done";
                
                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @kromignon said in Why QtConcurrent::run freezing my program?:

                You need to use QFutureWatcher in combination with QEventLoop to not lock you main thread.

                This contradicts the whole idea to move the heavy work into an own thread...

                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
                • Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by Christian Ehrlicher
                  #8

                  @isan said in Why QtConcurrent::run freezing my program?:

                  for(int u=0;u<Record.size();u++){
                  QStringList line=Record.split("#");
                  qDebug()<<"record list"<<line;

                  I hope this is not your real function since it basically does Record.size() times the same.

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

                  I 1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @isan said in Why QtConcurrent::run freezing my program?:

                    for(int u=0;u<Record.size();u++){
                    QStringList line=Record.split("#");
                    qDebug()<<"record list"<<line;

                    I hope this is not your real function since it basically does Record.size() times the same.

                    I Offline
                    I Offline
                    isan
                    wrote on last edited by isan
                    #9

                    @christian-ehrlicher
                    yes you said right, it should work without for()

                    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