Как заменить Qthread на QtConcurrent - PullRequest
0 голосов
/ 24 октября 2019

У меня есть класс извлечения SQL, который подключается к SQL и извлекает необходимые данные.

Я хотел сделать это в другой ветке, поэтому я сделал это с QThread. Он работает в порядке.

Но теперь я хочу заменить его на QTConcurrent. T Проблема, с которой я сталкиваюсь в QTconcureent, заключается в том, что мне нужна команда подключения , которая инициализирует базу данных, прежде чем поток использует SQL-запрос.

Вот мои коды, созданные в публичном слоте, а qint64TotalSize это публичный метод класса SqlFetcher.

Controller::Controller(QObject *parent) : QObject(parent)
{
    SqlFetcher* m_Fetcher = new SqlFetcher();

    qInfo() <<"Start"<< QThread::currentThread();

     QFutureWatcher<void> watcher;
     QFuture <void> future1 = QtConcurrent::run(m_Fetcher,&SqlFetcher::qint64TotalSize);

     watcher.setFuture(future1);


    //QThread* t1 = new QThread();
    //m_Fetcher->moveToThread(t1);

    //connect(t1, &QThread::started, m_Fetcher, &SqlFetcher::createDb);
    //connect(t1, &QThread::started, m_Fetcher, &SqlFetcher::qint64TotalSize);
    //t1->start();


    qInfo() <<"Finish"<< QThread::currentThread();

}

void SqlFetcher::qint64TotalSize()
{
    qint64 l_result= 0;
    QSqlQuery l_query;

    if (m_sqldb.isValid())
    {
        m_sqldb.open();

        if ((m_sqldb.isOpen()))
        {
            l_query.prepare("SELECT COUNT(*) FROM table1");
            l_query.exec();

            if (l_query.next()) {
                l_result= l_query.value(0).toInt();
            }
            m_sqldb.close();
        }
    }

    qInfo() << l_result << QThread::currentThread();
}

void SqlFetcher::createDb()
{
    m_sqldb = QSqlDatabase::addDatabase("QSQLITE");
    m_sqldb.setDatabaseName("xyz.db");
     qInfo() << "createDB" << QThread::currentThread();
}


Мой текущий вывод

Start QThread(0x7feab4c0f060)
Finish QThread(0x7feab4c0f060)
0 QThread(0x7feab4d42070, name = "Thread (pooled)")

Ожидаемый вывод или вывод с Qthread is

Start QThread(0x7fe82140f060)
Finish QThread(0x7fe82140f060)
createDB QThread(0x7fe82155c840)
151 QThread(0x7fe82155c840)

1 Ответ

1 голос
/ 24 октября 2019

Попробуйте выполнить всю задачу за run, например,

QtConcurrent::run([](){

    SqlFetcher m_Fetcher;
    m_Fetcher.createDb();
    m_Fetcher.qint64TotalSize();
});

Поскольку мы имеем дело с параллелизмом, безопаснее использовать именованные соединения (в противном случае одно и то же соединение по умолчанию будет использоваться каждый раз,возможно более чем одним потоком). Вы можете управлять этим, добавив аргумент к SqlFetcher::createDb:

void SqlFetcher::createDb(const QString & connectionName)
{
    m_sqldb = QSqlDatabase::addDatabase("QSQLITE", connectionName);
    // etc.

, а также к лямбде и функции run:

QtConcurrent::run([](const QString & cn){

    SqlFetcher m_Fetcher;
    m_Fetcher.createDb(cn);
    m_Fetcher.qint64TotalSize();
}, QString("TheConnectionName"));

В другой функции,назначить базу данных для запроса, в разработке:

void SqlFetcher::qint64TotalSize()
{
    qint64 l_result= 0;
    QSqlQuery l_query(m_sqldb);
    //etc.
...