繁体   English   中英

辅助线程中的QTimer

[英]QTimer in worker thread

我有一个Worker类,它在另一个线程中做一些工作,使用moveToThread()将其放置在其中。 Worker::doWork()方法内部,我还创建了一个QTimer ,该QTimer应该根据任务所需的估计时间发出进度更新。

这是一个例子:

ThreadController::ThreadController()
{
    Worker* worker = new Worker;
    worker->moveToThread(&m_workerThread);

    // ...        

    m_workerThread.start();
    emit startWorker(params); // connected to Worker::doWork()
}


class Worker : public QObject
{
    Q_OBJECT

public slots:
    Worker::doWork(const QString& params)
    {
        QTimer* timer = new QTimer(this);
        connect( timer, SIGNAL(timeout)), this, SLOT(updateProgress()) );
        timer->start(estimateTaskLength() / 100);

        // perform work...
    }
}

现在,这无法按预期进行。 仅在工作完成后才开始调用updateProgress()插槽。

当计时器到期时, timeout事件将排队到工作线程QThread的事件队列中。 但是,您的工作者QThread忙于执行doWork() ,因此无法处理该事件。 一旦线程完成doWork ,控件将返回QThread的事件循环并执行timeout事件。

解决此问题的最简单方法是在执行doWork()过程中以一定间隔使用QCoreApplication::processEvents()手动调用事件循环。 这将使QThread可以更早地执行timeout事件。

或者,您可以使用其他线程来执行这些估计。 如果它们不太注重性能,那么您甚至可以使用GUI /主线程。 GUI /主线程应保持对事件的“响应”(否则应用程序似乎挂起),因此它可以及时处理timeout事件。

这可能取决于Qtimer :: timeout和this :: updateProgress之间的连接类型。

默认情况下,它是Qt :: AutoConnection,这意味着超时信号将排队,直到接收对象准备好处理它为止。 即在doWork完成之后。

如果使用

connect( timer, SIGNAL(timeout)), this, SLOT(updateProgress()), Qt::DirectConnection );

超时信号应立即处理。 (但是请确保包括必要的互斥对象和填充,因为这是典型的情况,例如可能发生并发访问。)

http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM