在取消线程上使用 QFuture 释放内存
Free memory using QFuture on cancel thread
我正在编写一个使用 QtConcurrent
启动线程的程序。在我的例子中,当我使用鼠标滚动时,我用它来渲染 QGraphicsView。
我正在使用以下代码启动线程:
if (future.isRunning()) {
future.cancel();
}
future = QtConcurrent::run(this,&AeVectorLayer::render, renderparams, pos);
watcher.setFuture(future);
线程完成后,我用 QfutureWatcher
.
捕获信号 finished
这是我的渲染函数:
QList<AeGraphicsItem*> AeVectorLayer::render(Ae::renderParams renderparams, int pos)
{
AeVectorHandler *coso = new AeVectorHandler();
coso->openDataset(AeLayer::absoluteFilePath);
coso->setTransformCoordinates(myEPSG);
QList<AeGraphicsItem*> bla = coso->getItems(renderparams.sceneRect.x(),
renderparams.sceneRect.y(), renderparams.sceneRect.width(),
renderparams.sceneRect.height(), renderparams.zoom, color, this);
for (int i = 0; i < bla.size(); i++)
bla.at(i)->setZValue((qreal)pos);
delete coso;
return bla;
}
如您所见,我的渲染函数中有一个 QList<QGraphicsItem*>
。当未来被取消时,我如何销毁这个列表?我不明白在我的代码中我正在重新定义 future
变量,但我不知道如何避免它。
停止尝试手动管理内存,而是使用适合您的用例的智能指针。因为你使用移动不感知 QFuture
,你将需要一个 std::shared_ptr
。一旦 QFuture
/QFutureWatcher
超出范围,并且您不再持有 shared_ptr
个实例,资源将被删除。因此,在您的情况下,您的 render
函数应该 return a QList<std::shared_ptr<AeGraphicsItem>>
。将所有权从 shared_ptr
转移到例如a QGraphicsScene
:您必须 release
来自 shared_ptr
所有权转让。
请注意,您的 isRunning
检查后跟 cancel
从根本上来说是有缺陷的:当您调用 isRunning
时,未来可能是 运行 但在您调用时已经完成cancel
。如果你想取消它,只需调用cancel
。另请注意,您不能有意义地取消由 QtConcurrent::run
编辑的 QFuture
s return,因此您所做的事情本身就非常错误。
我正在编写一个使用 QtConcurrent
启动线程的程序。在我的例子中,当我使用鼠标滚动时,我用它来渲染 QGraphicsView。
我正在使用以下代码启动线程:
if (future.isRunning()) {
future.cancel();
}
future = QtConcurrent::run(this,&AeVectorLayer::render, renderparams, pos);
watcher.setFuture(future);
线程完成后,我用 QfutureWatcher
.
finished
这是我的渲染函数:
QList<AeGraphicsItem*> AeVectorLayer::render(Ae::renderParams renderparams, int pos)
{
AeVectorHandler *coso = new AeVectorHandler();
coso->openDataset(AeLayer::absoluteFilePath);
coso->setTransformCoordinates(myEPSG);
QList<AeGraphicsItem*> bla = coso->getItems(renderparams.sceneRect.x(),
renderparams.sceneRect.y(), renderparams.sceneRect.width(),
renderparams.sceneRect.height(), renderparams.zoom, color, this);
for (int i = 0; i < bla.size(); i++)
bla.at(i)->setZValue((qreal)pos);
delete coso;
return bla;
}
如您所见,我的渲染函数中有一个 QList<QGraphicsItem*>
。当未来被取消时,我如何销毁这个列表?我不明白在我的代码中我正在重新定义 future
变量,但我不知道如何避免它。
停止尝试手动管理内存,而是使用适合您的用例的智能指针。因为你使用移动不感知 QFuture
,你将需要一个 std::shared_ptr
。一旦 QFuture
/QFutureWatcher
超出范围,并且您不再持有 shared_ptr
个实例,资源将被删除。因此,在您的情况下,您的 render
函数应该 return a QList<std::shared_ptr<AeGraphicsItem>>
。将所有权从 shared_ptr
转移到例如a QGraphicsScene
:您必须 release
来自 shared_ptr
所有权转让。
请注意,您的 isRunning
检查后跟 cancel
从根本上来说是有缺陷的:当您调用 isRunning
时,未来可能是 运行 但在您调用时已经完成cancel
。如果你想取消它,只需调用cancel
。另请注意,您不能有意义地取消由 QtConcurrent::run
编辑的 QFuture
s return,因此您所做的事情本身就非常错误。