首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Qt终止由QConcurrent::run生成的线程

Qt终止由QConcurrent::run生成的线程
EN

Stack Overflow用户
提问于 2013-03-13 12:42:15
回答 1查看 1.3K关注 0票数 2

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

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

代码语言:javascript
运行
复制
void MainWindow::runLengthyJob() {
    /* some setup */
    jobWatcher->setFuture(QConcurrent::run(theApp, &AppClass::lengthyJob));
    // lengthyJob - can be readPop(), writePop(), runSim()
}

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

代码语言:javascript
运行
复制
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 () /writePop(),这些都是自包含的函数,我不能将其分解为更小的步骤。对于AppClass::runSim(),可能需要更小的步骤。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-13 13:47:59

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

无论哪种方式,如果你想通知用户任务正在运行,你可以这样做:创建一个QDialog的子类,比如用带句点的QTimer创建WaitDialog,在构造对话框时启动这个计时器,将timeout()信号连接到这个对话框中的某个插槽,如果没有正在运行的线程,就接受这个对话框:

代码语言:javascript
运行
复制
if (QThreadPool::globalInstance()->activeThreadCount() == 0)
    accept();

然后在MainWindow::closeEvent中:

代码语言:javascript
运行
复制
void MainWindow::closeEvent(QCloseEvent *event) {
    WaitDialog dlg;
    dlg.exec();
    event->accept();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15377236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档