Can I search for files via QtConcurrent?



  • I need to find files on my HDD (recursively).
    But it takes a long of time and GUI freezes.
    I try to solve it via QtConcurrent:
    @void MainWindow::on_buttonSearch_clicked()
    {
    QFutureWatcher<QFileInfoList> watcher;
    connect(&watcher, SIGNAL(finished()), this, SLOT(loadFinished()));
    future = QtConcurrent::run(&MainWindow::searchForFiles, lineEditInDir->text()); // in .h QFuture<QFileInfoList> future;
    watcher.setFuture(future);
    }

    QFileInfoList MainWindow::searchForFiles(const QString &startDir)
    {
    QDir dir(startDir);
    QFileInfoList list;
    foreach (QString file, dir.entryList(QStringList("*.svg"), QDir::Files))
    list += QFileInfo(startDir+"/"+file);
    foreach (QString subdir, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot))
    list += searchForFiles(startDir+"/"+subdir);
    return list;
    }

    void MainWindow::loadFinished()
    {
    fileList = future.result();
    qDebug()<<fileList.count();
    }@

    All works fine, I think, but I can't cancel it. future.cancel() didn't work, because I use QtConcurrent::run().
    And i don't know how to put files search into QtConcurrent::mapped(), which can be canceled.



  • I think it would be useless to use QtConcurrent for this. QtConcurrent is suitable for problems that are are easy to parallelize. Searching your HDD will have I/O as the bottleneck, so using multiple threads to do that is not efficient. The threads will end up waiting for each other.

    So, I would use either a QObject derived worker that you move to a vanilla [[doc:QThread]], or a [[doc:QRunnable]] subclass in conjunction with [[doc:QThreadPool]]. Because you seem to need cancel capabilities, I think the QThread route would be easiest.



  • Using QtConcurrent can even worse the situation as OS caches might get flushed once the next thread is running and the data needs to be re-read if the first thread is active again.


Log in to reply
 

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