如何告诉 QThread 等待工作完成,然后完成?

发布于 2024-10-31 04:03:47 字数 1125 浏览 0 评论 0原文

我有一个使用一个工作线程的简单应用程序。 这个工作线程启动并初始化DownloadManager,它负责从网络下载文件。 在我的主应用程序类中,我在 DownloadManager 完成之前发出的线程上有 finish() 信号。

我的问题是如何让工作线程等待 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 

     .....
     .....
 }

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 

     .....
     .....
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩起发的微风 2024-11-07 04:03:47

如果您在异步操作完成时发出信号,则始终可以使用 QEventLoop 将异步操作“转变”为与当前线程同步。它仍然是异步的,但线程将“等待”它完成。

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

所以基本上你把它放在你想要同步执行网络请求的 DownloadManager 类中。一旦循环的 quit 槽被调用,exec() 将返回。

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.

相守太难 2024-11-07 04:03:47

您可以使用 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 需要对多线程有很好的理解。

希望有帮助

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文