プラットフォーム: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」ボタンをクリックすると、アプリが最終的に終了したにもかかわらず、フリーズして「応答していません」(テキストはOSから提供されていると思います)と表示されているようです。
MainWindowのclose()スロットがトリガーされたらすぐにアプリを終了したい。では、まだ完成していないスレッドの待機時間を短縮するにはどうすればよいでしょうか。または、実行中の長いジョブがまだあることをユーザーに通知するにはどうすればよいですか(完全にシャットダウンするまでに数時間かかる場合があります)。(closeEventにQDialog / QMessageboxを含めようとしましたが、新しく作成されたウィジェットもフリーズします)
注:AppClass:lengthyJobs [readPop()/ writePop()]の場合、これらは自己完結型の関数であり、小さなステップに分解することはできません。AppClass :: runSim()の場合、より小さなステップが可能になる場合があります。