我有一个使用一个工作线程的简单应用程序。 启动此工作线程并初始化DownloadManager,它负责从网络下载文件。 在我的主应用程序类中,我在DownloadManager完成之前发出的线程上有完成的()SIGNAL。
我的问题是如何使工作线程等到DownloadManager完成其工作。
以下是示例代码:
class Main
{
m_DownloadWorker = new DownloadWorker(this);
QObject::connect(pm_hotosDownloadWorker, SIGNAL(finished()), this, SLOT(DownloadWorkerFinished()));
m_DownloadWorker->Execute();
// do i need to do here something so the thread will wait ?
.....
void Main::DownloadWorkerFinished()
{
Log("DownloadWorkerFinished");
}
};
class DownloadWorker : public QThread
{
void DownloadWorker::Execute()
{
// do i need to do here somthing so the thread will wait ?
start();
}
void DownloadWorker::run()
{
// do i need to do here somthing so the thread will wait ?
DownloadManager* pDownloadManager = new DownloadManager(this);
pDownloadManager->download();
}
};
class DownloadManager: public QObject
{
// downloading stuff using Qt networkmanager
.....
.....
}
答案 0 :(得分:4)
如果在异步操作完成时发出信号,则可以始终使用QEventLoop将异步操作“转”为与当前线程同步。它仍然是异步的,但线程将“等待”它完成。
QNetworkAccessManager nam;
QEventLoop loop;
QNetworkReply *reply = nam.get(request);
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
所以基本上你把它放在你想要同步进行网络请求的DownloadManager类中。一旦调用了循环的exec()
插槽,quit
将返回。
答案 1 :(得分:3)
您可以使用QThread::exec()调用在事件循环中运行您的线程。线程将运行它,直到您通过调用QThread::exit()告诉您的线程退出。所以一些示例代码可能如下所示:
void DownloadWorker::run()
{
DownloadManager* pDownloadManager = new DownloadManager(this);
connect(pDownloadManager, SIGNAL(finished()), SLOT(exit()));
connect(pDownloadManager, SIGNAL(error()), SLOT(exit()));
pDownloadManager->download();
exec();
}
这样可以保证在发出DownloadManager的“finished()”信号之前你的线程不会退出。
注意:这里我举例说明如何解决您的问题,但我不知道您的整个应用程序代码。这意味着无法保证此代码是线程安全且一致的。您需要自己处理互斥锁和所有正确的同步。要非常小心 !使用这种“低级”线程API需要很好地理解多线程。
希望有所帮助