#ifndef CONCURRENTTASKMGR_H
#define CONCURRENTTASKMGR_H
#include <QObject>
#include <QVariant>
#include <QReadWriteLock>
#include <QFutureWatcher>
class ConcurrentTaskMgr : public QObject
{
Q_OBJECT
public:
explicit ConcurrentTaskMgr(QObject *parent = nullptr);
virtual void startTask(const QVariant& variant) final;
virtual void startTask() final;
virtual bool doTask() = 0;
virtual void taskFinished() = 0;
public slots:
virtual void sltTaskFinished();
protected:
QReadWriteLock m_rwLock;
QVariant m_variant;
QFutureWatcher<bool> m_watcher;
};
#endif // CONCURRENTTASKMGR_H
#include "ConcurrentTaskMgr.h"
#include <QFuture>
#include <QtConcurrent>
ConcurrentTaskMgr::ConcurrentTaskMgr(QObject *parent) : QObject(parent),
m_rwLock(QReadWriteLock::Recursive)
{
connect(&m_watcher, SIGNAL(finished()), this, SLOT(sltTaskFinished()));
}
void ConcurrentTaskMgr::startTask(const QVariant &variant)
{
QWriteLocker locker(&m_rwLock);
if (m_variant == variant)
{
return;
}
m_watcher.cancel();
m_watcher.waitForFinished();
m_variant = variant;
QFuture<bool> future = QtConcurrent::run(this, &ConcurrentTaskMgr::doTask);
m_watcher.setFuture(future);
}
void ConcurrentTaskMgr::startTask()
{
m_watcher.cancel();
m_watcher.waitForFinished();
QFuture<bool> future = QtConcurrent::run(this, &ConcurrentTaskMgr::doTask);
m_watcher.setFuture(future);
}
void ConcurrentTaskMgr::sltTaskFinished()
{
QWriteLocker locker(&m_rwLock);
taskFinished();
}
=====================================================================
#ifndef READDATAMGR_H
#define READDATAMGR_H
#include "ConcurrentTaskMgr.h"
class ReadDataMgr : public ConcurrentTaskMgr
{
Q_OBJECT
public:
explicit ReadDataMgr(QObject *parent = nullptr);
void readData();
bool doTask() override;
void taskFinished() override;
signals:
void sglReadFinshed();
public slots:
};
#endif // READDATAMGR_H
#include "ReadDataMgr.h"
#include <QFile>
#include <QDebug>
#include <QThread>
ReadDataMgr::ReadDataMgr(QObject *parent) : ConcurrentTaskMgr(parent)
{
}
void ReadDataMgr::readData()
{
startTask();
}
bool ReadDataMgr::doTask()
{
qDebug()<<"doTask"<<QThread::currentThreadId();
for(int i=0; i<10000; ++i)
{
qDebug()<<"i="<<i;
}
return true;
}
void ReadDataMgr::taskFinished()
{
emit sglReadFinshed();
}
======================================================================
//test
ReadDataMgr readDataMgr;
connect(&readDataMgr, &ReadDataMgr::sglReadFinshed, this, &MainWindow::sltReadFinshed);
void MainWindow::sltReadFinshed()
{
qDebug()<<"sltReadFinshed";
qDebug()<<QThread::currentThreadId();
}