Results 1 to 10 of 10

Thread: Qt application doesn't close properly during QEventloop

  1. #1
    Join Date
    Oct 2013
    Posts
    14
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Qt application doesn't close properly during QEventloop

    Hi guys, so i'm handling network manager calls in a different thread. When the thread is running and performing a POST, and i close the window, the application is still running in the debugger without stopping (unless i manually press stop button). I think it might have to do with the event loop but i'm not too sure. Can someone help?

    here is my POST method:

    Qt Code:
    1. QNetworkReply *ApiManager::DoHttpPost(QNetworkAccessManager *NetworkManager, const QUrl &Url, QString Data)
    2. {
    3. QNetworkRequest Request(Url);
    4.  
    5. QNetworkReply *Reply = NetworkManager->post(Request,Data.toUtf8());
    6. Reply->setProperty("Timeout",false);
    7.  
    8. //Wait for the reply and add a timeout period
    9. QTimer Timer;
    10. Timer.setSingleShot(true);
    11. Timer.setInterval(10000);
    12.  
    13. QEventLoop Loop;
    14. QObject::connect(&Timer,SIGNAL(timeout()),&Loop,SLOT(quit()));
    15. QObject::connect(&Timer,&QTimer::timeout,[=]() { Reply->setProperty("Timeout",true); });
    16. QObject::connect(Reply,SIGNAL(finished()),&Loop,SLOT(quit()));
    17. Timer.start();
    18. Loop.exec();
    19.  
    20. return Reply;
    21. }
    To copy to clipboard, switch view to plain text mode 

    here is where i make my thread:
    Qt Code:
    1. QThread *Thread = Thread_Manager.GetThread();
    2. Worker = new QueueWorker(ItemQueue);
    3. Worker->moveToThread(Thread);
    4.  
    5. //Connect signals and slots
    6. connect(Thread,SIGNAL(started()),Worker,SLOT(Run()));
    7. connect(Worker.data(),SIGNAL(DeleteQueueItem(QueueItem*)),this,SLOT(DeleteItem(QueueItem*)));
    8. connect(Worker.data(),SIGNAL(Finished()),Thread,SLOT(quit()));
    9. connect(Worker.data(),SIGNAL(Finished()),Worker.data(),SLOT(deleteLater()));
    10. connect(Worker.data(),SIGNAL(AuthUser()),this,SLOT(AuthenticateUser()));
    11.  
    12. //Make sure not to manually delete the thread, instead send it to the thread manager to delete
    13. connect(Thread,&QThread::finished,[=](){
    14. Thread_Manager.DeleteThread(Thread);
    15. Running = false;
    16. emit PopulateModel();
    17. });
    18. Thread->start();
    To copy to clipboard, switch view to plain text mode 

    Thread_Manager creates threads and adds them to a list, on deletion of the manager it deletes the threads in the list.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt application doesn't close properly during QEventloop

    Do you signal your threads to stop when the window is closed?

    Anyway, stupid questions: why use threads for things that are non-blocking by default?

    Cheers,
    _

  3. #3
    Join Date
    Oct 2013
    Posts
    14
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt application doesn't close properly during QEventloop

    i call this code in the destructor of the thread manager
    Qt Code:
    1. foreach(QThread *Thread, ActiveThreadList)
    2. {
    3. Thread->quit();
    4. Thread->wait(); //Application hangs here
    5.  
    6. DeleteThread(Thread);
    7. }
    To copy to clipboard, switch view to plain text mode 

    also not a stupid question, in this application i need to complete certain network requests in order, so i synchronously wait for the reply, doing this in the main thread freezes the GUI so i moved it to another one.

    EDIT: I did some testing and it turns out that the thread hangs on the wait call, anyone have any idea?
    Last edited by jigglyslime; 4th November 2013 at 12:45.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt application doesn't close properly during QEventloop

    Well, wait() needs to wait until the other thread exited. If that thread is currently doing something blocking, then the caller will have to wait until that is done and the thread has returned to its event loop processing.

    So in your case, check if one of your threads is currently in one of those blocking calls.

    If I may make a suggestion: don't use threads since you don't need them.

    Doing a sequence of requests can usually easily be done full asynchronously, e.g. by creating a list of tasks and then taking them one by one and executing them.

    Can you give a hint on how your sequence looks like?

    Cheers,
    _

  5. #5
    Join Date
    Oct 2013
    Posts
    14
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt application doesn't close properly during QEventloop

    Doing a sequence of requests can usually easily be done full asynchronously, e.g. by creating a list of tasks and then taking them one by one and executing them.
    How would i go about implementing this?

    Can you give a hint on how your sequence looks like?
    so basically first and foremost i must make a login request to the server, so i send over the auth data
    then i get some user information from the server (only works if user has been authenticated, also there's about 4 files that need to be taken)

    then when the user updates something, i send that information to the server.

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt application doesn't close properly during QEventloop

    If I have something that is a composition of asynchronous tasks, I usually go for a "job" pattern

    Basically you have an abstract class that defines the interface for your task, e.g.
    Qt Code:
    1. class Job : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. Job( /* .. your common parameters here */, QObject *parent = 0 );
    7.  
    8. virtual void start() = 0;
    9.  
    10. int error() const; // either with an error code member or also pure virtual
    11.  
    12. signals:
    13. voif finished( Job *job );
    14. };
    To copy to clipboard, switch view to plain text mode 

    Usually combined with a job queue that automatically runs one job at a time
    Qt Code:
    1. class JobQueue : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. void append( Job *job );
    7.  
    8. private:
    9. QQueue<Job*> m_jobs;
    10.  
    11. private slots:
    12. void runNextJob();
    13. void onJobFinished( Job *job );
    14. };
    To copy to clipboard, switch view to plain text mode 
    The queue can either stop if a job finished with an error, or the job can indicate if it should be repeated, or you handle the error outside and prepend() the same job if it has to run
    This is very much like QNetworkRequest itself.

    This is very much like QNetworkRequest itself, i.e. it also has internal state tracking and signals when it is done.

    Cheers,
    _

  7. #7
    Join Date
    Oct 2013
    Posts
    14
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt application doesn't close properly during QEventloop

    That's what i'm currently doing, i have a class called QueueItem that directly interfaces with the network class and calls the post methods. Then i have the QueueManager which runs the queue item in a for loop. But the thing is, when i remove the event loop and replace it with a signal and slot connection, the queue manager runs all the QueueItem start functions and they don't return in order that they were executed in.

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt application doesn't close properly during QEventloop

    Right, this is what I meant with "the queue runs one job at a time"

    Qt Code:
    1. class JobQueue : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. explicit JobQueue( QObject *parent = 0 );
    7. void append( Job *job );
    8.  
    9. private:
    10. QQueue<Job*> m_jobs;
    11. bool m_running;
    12.  
    13. private slots:
    14. void runNextJob();
    15. void onJobFinished( Job *job );
    16. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. JobQueue::JobQueue( QObject *parent = 0 )
    2. : QObject( parent )
    3. , m_running( false )
    4. {
    5. }
    6.  
    7. void JobQueue::append( Job *job )
    8. {
    9. m_jobs << job;
    10. connect( job, SIGNAL(finished(Job*)), this, SLOT(onJobFinished(Job*)) );
    11.  
    12. // schedule job execution
    13. QMetaObject::invokeMethod( this, "runNextJob", Qt::QueuedConnection );
    14. }
    15.  
    16. void JobQueue::runNextJob()
    17. {
    18. if ( m_running || m_jobs.isEmpty() )
    19. return;
    20.  
    21. m_running = true;
    22.  
    23. m_jobs->dequeue()->start();
    24. }
    25.  
    26. void JobQueue::onJobFinished( Job *job )
    27. {
    28. m_running = false;
    29.  
    30. if ( job->error() != 0 )
    31. return; // TODO actual error handling
    32.  
    33. runNextJob();
    34. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  9. The following user says thank you to anda_skoa for this useful post:

    jigglyslime (6th November 2013)

  10. #9
    Join Date
    Oct 2013
    Posts
    14
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt application doesn't close properly during QEventloop

    Oh i see what you mean, Thanks

  11. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt application doesn't close properly during QEventloop

    You can also easily create composite jobs, i.e. a job that contains a job queue and runs a series of sub jobs before it emits its own finished() signal.

    Cheers,
    _

Similar Threads

  1. mouseMoveEvent doesn't respond properly
    By Ponnytail in forum Newbie
    Replies: 2
    Last Post: 4th November 2013, 19:45
  2. How to close (exit) a dialog properly
    By cooper in forum Newbie
    Replies: 6
    Last Post: 9th March 2011, 19:19
  3. Replies: 2
    Last Post: 17th December 2010, 19:01
  4. Properly close database handlers
    By ruben.rodrigues in forum Newbie
    Replies: 5
    Last Post: 23rd September 2010, 16:10
  5. Delegate doesn't paint properly
    By woodtluk in forum Qt Programming
    Replies: 4
    Last Post: 11th August 2010, 11:43

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.