如何用 QtConcurrent 替换 Qthread
How to replace Qthread with QtConcurrent
我有一个 SQL 获取 class 连接到 SQL 并获取所需的数据。
我想在另一个线程中这样做,所以我用 QThread 做到了。
它正常工作。
但是现在我想用QTConcurrent代替它。 T我在使用 QTconcureent 时遇到的问题是我需要一个连接命令,它在线程用于执行 SQL 查询之前初始化数据库。
这是我创建的代码,是 public 插槽,qint64TotalSize 是 SqlFetcher class 的 public 方法。
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 的预期输出或输出是
Start QThread(0x7fe82140f060)
Finish QThread(0x7fe82140f060)
createDB QThread(0x7fe82155c840)
151 QThread(0x7fe82155c840)
尝试在 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.
以及 lambda 和 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.
我有一个 SQL 获取 class 连接到 SQL 并获取所需的数据。
我想在另一个线程中这样做,所以我用 QThread 做到了。 它正常工作。
但是现在我想用QTConcurrent代替它。 T我在使用 QTconcureent 时遇到的问题是我需要一个连接命令,它在线程用于执行 SQL 查询之前初始化数据库。
这是我创建的代码,是 public 插槽,qint64TotalSize 是 SqlFetcher class 的 public 方法。
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 的预期输出或输出是
Start QThread(0x7fe82140f060)
Finish QThread(0x7fe82140f060)
createDB QThread(0x7fe82155c840)
151 QThread(0x7fe82155c840)
尝试在 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.
以及 lambda 和 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.