QFuture信号在错误的时间发出

时间:2015-03-09 20:55:48

标签: c++ windows multithreading qt

我尝试使用QT的QFuture和QFutureWatcher来实现带有通知的工作线程,但通知未在正确的时间到来!

我从菜单处理程序调用{​​{1}},并期望在工作线程中发生加载,以及发生了什么。但loadFile(QString)在执行ibLoadFinished()之后立即被调用,而不是在退出之后 connect。 (磁盘访问在IBF构造函数中完成。)

我做错了什么?

ImageViewer.h:

LoadFromDisk()

ImageViewer.cpp:

class ImageViewer : public QMainWindow
{
  Q_OBJECT
public:
  static IBF* LoadFromDisk(const QString& filename);

private:
  QFuture<IBF*> ibfLoadedFuture;
  QFutureWatcher<IBF*> ibfLoadedFutureWatcher;

private slots:
  //...
  Q_SLOT void ibLoadFinished();
}

1 个答案:

答案 0 :(得分:2)

虽然文档中没有明确说明,但只要您从QFutureWatcher::setFuture获得新的QFuture,就必须调用QtConcurrent::run(),这意味着您无法调用setFutureImageViewer的构造函数中,就像你所做的那样。此外,由于QFuture提供了确定并发任务是否仍在运行的方法,因此不必将QFutureWatcher保留为您的班级成员。

总之,从构造函数中删除此行: ibfLoadedFutureWatcher.setFuture(ibfLoadedFuture);

然后将loadFile的实施更改为以下内容:

bool ImageViewer::loadFile(const QString& filename)
{
  if (ibfLoadedFutureWatcher.isRunning())
    return false;
  QFuture<IBF*> ibfLoadedFuture = QtConcurrent::run(LoadFromDisk, filename);
  ibfLoadFutureWatcher.setFuture(ibfLoadedFuture);
  return true;
}

此外,您可以使用QFutureWatcher::result()

从并发运行中获取结果
void ImageViewer::ibLoadFinished()
{    
  IBF* ibf = ibfLoadedFutureWatcher.result();
  process(*ibf);
  delete ibf;
}