It is not generally possible. Some QFuture
s - not the ones returned by QtConcurrent::run
, though - are cancellable. If you're using QtConcurrent::run
, or submitting a generic QRunnable
, you need to make it cancellable. This answer provides a way of generating a cancellable future that runs on the thread pool. You then need to keep track of those futures and cancel any that are in progress.
Generally speaking, there's no need to dynamically create the thread pool - just store it by value. And once you use a QFuture
interface, there's no need to manage the lifetime of the tasks either: the futures are handles for this object, and once the last one goes away, the task object is released.
class HelloWorldTask : RunControllableTask<void> {
// see https://stackoverflow.com/a/16729619/1329652
...
};
class MainWindow : public QMainWindow {
QThreadPool m_pool;
QVector<QFuture<void>> m_futures;
public:
explicit MainWindow(QWidget * parent = {}) : QMainWindow(parent) {
m_pool.setMaxThreadCount(1);
}
void startTask() {
auto future = TaskExecutor::run(new HelloWorldTask());
m_futures.push_back(future);
}
void stopAllTasks() {
m_pool.cancel();
for (auto &future : m_futures)
future.cancel();
while (!m_futures.isEmpty())
m_futures.takeLast().waitForFinished(); // this will free the task too!
Q_ASSERT(!m_pool.activeThreadCount());
}
~MainWindow() override {
stopAllTasks();
}
};
You can use the future interface to thread-safely return data back from the task, too!