gpt4 book ai didi

c++ - Qt 终止由 QConcurrent::run 生成的线程

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:57:54 25 4
gpt4 key购买 nike

平台:Win7 x64、MinGW-rubenvb (4.7.2-x64)、Qt 4.8

假设我有几个使用 QConcurrent::run 生成的冗长任务(读取填充文件、写入填充文件和运行模拟),如下所示:

void MainWindow::runLengthyJob() {
/* some setup */
jobWatcher->setFuture(QConcurrent::run(theApp, &AppClass::lengthyJob));
// lengthyJob - can be readPop(), writePop(), runSim()
}

通常这些任务至少需要 15 秒才能完成(对于模拟,需要数小时以上)。为了防止因尚未完成的线程而崩溃,我重新实现了 MainWindow::closeEvent,如下所示:

void MainWindow::closeEvent(QCloseEvent *event) {
/* wait for any dangling thread */
if (QThreadPool::globalInstance()->activeThreadCount())
QThreadPool::globalInstance()->waitForDone();
event->accept();
} // end: MainWindow::closeEvent

这没问题,但是当我单击 MainWindow 的“x”按钮时,它似乎卡住并显示“无响应”(我猜文本是由操作系统给出的),尽管它最终终止了应用程序。

我想在 MainWindow 的 close() 插槽被触发后立即退出应用程序。那么,如何缩短未完成线程的等待时间呢?或者我如何通知用户还有一个冗长的作业在运行(这可能需要几个小时才能完全关闭)? (我试图在 closeEvent 中包含 QDialog/QMessagebox 但新创建的小部件也卡住了)

注意:对于 AppClass:lengthyJobs [readPop()/writePop()],这些是独立的函数,我无法分解为更小的步骤。对于 AppClass::runSim(),可能需要更小的步骤。

最佳答案

首先,QtConcurrent::run 返回的 future 不支持取消。所以你不能直接取消它。你能做的最好的事情是在 AppClass 中设置一些标志并在你的 lengthyJobs 中检查它(正如你所说的在 runSim 的情况下是可能的),然后等待完成。

无论哪种方式,如果你想通知用户正在运行的任务,你可以执行以下操作:创建一个 QDialog 的子类,比如 WaitDialog 和 QTimer 有一些周期,在对话框构建时启动这个计时器,将 timeout() 信号连接到一些在此对话框中插入插槽,如果没有正在运行的线程,则接受该对话框:

if (QThreadPool::globalInstance()->activeThreadCount() == 0)
accept();

然后在 MainWindow::closeEvent 中:

void MainWindow::closeEvent(QCloseEvent *event) {
WaitDialog dlg;
dlg.exec();
event->accept();
}

关于c++ - Qt 终止由 QConcurrent::run 生成的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15377236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com