How to tell QThread to wait until work is done ,an

2019-08-15 19:02发布

I have a simple application that uses one worker thread. This worker thread is started and initializes DownloadManager, which is responsible for downloading files from the net. In my main application class I have the finished() SIGNAL on the thread that is emitted before the DownloadManager finishes.

My question is how to make the worker thread wait until the DownloadManager finishes its work.

Here is example code :

 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 

     .....
     .....
 }

标签: c++ qt4 qthread
2条回答
SAY GOODBYE
2楼-- · 2019-08-15 19:35

In cases when you have a signal that is emitted when an asynchronous operation is completed, you can always use QEventLoop to "turn" the asynchronous operation into synchronous with the current thread. It is still asynchronous, but the thread will "wait" for it to finish.

QNetworkAccessManager nam;
QEventLoop loop;
QNetworkReply *reply = nam.get(request); 
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();

So basically you put this in you DownloadManager class where you want to do a network request synchronously. exec() will return once the loop's quit slot has been called.

查看更多
Luminary・发光体
3楼-- · 2019-08-15 19:50

You can use QThread::exec() call to run your thread in the event loop. The thread will run it until you tell your thread to exit by calling QThread::exit(). So some sample code can look like this:

void DownloadWorker::run()
 {
    DownloadManager* pDownloadManager = new DownloadManager(this);
    connect(pDownloadManager, SIGNAL(finished()), SLOT(exit()));
    connect(pDownloadManager, SIGNAL(error()), SLOT(exit()));
    pDownloadManager->download();
    exec();
 }

That would guarantee you that your thread won't quit until the "finished()" signal of your DownloadManager is issued.

Note: Here I put an example of how to solve your problem but I don't know your whole app code. That means there is not guarantee this code is thread safe and consistent. You need to take care of the mutexes and all the correct synchronization yourself. Be very careful ! Working with such a "low level" thread API requites good understanding of multithereading.

Hope that helps

查看更多
登录 后发表回答