Starting a download process in another thread can't help fixing the GUI hang problem
-
I am trying to download provided a url. If the url is a location on my local machine (hard drive) and if the download file size is large - more than 1 GB for instance, the GUI hangs. A logical solution to the problem is to use a separate (worker) thread that does the upload/download and disk writing work. The same problem is discussed "here":http://qt-project.org/forums/viewthread/711.
This GUI hang is reproduced only when downloading from the my hard drive (for test purposes) e.g. as if doing a file copy operation.
I presume that the reason why it is reproduced only it this situation is that the download speed is much higher that downloading from a remote host through the http protocol. So, there is no difference between the threaded and non-threaded approaches in this case. I am doing something wrong.The code for the whole project is located "here":http://code.google.com/p/threadtest/downloads/list.
-
The thread-specific question:
What needs to be fixed in this example and more specifically in the second (worker) thread management, so that there is no GUI thread hang?The more general question is:
How to download a large-sized file from the local disk and save it, again, to the local disk without having the GUI freeze? -
just providing a link to the complete project and expecting people to go through that and then find and solve your problem for you is expecting a bit too much. I suggest you analyse your code and locate the bottleneck and then you can just post the code related to your problem and ask for any suggestions.
Just a few general hints I can think of: Make sure you're using QThreads "correctly":http://qt-project.org/wiki/QThreads_general_usage and for communication between threads only use signal-slot connections.
-
First of all, I would like to suggest you this article: "How To Really, Truly Use QThreads; The Full Explanation":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
In your code i see 2 general problems:
- You use onFinished slot to save you data. Were will be saved 1GB before it gets to this function? Use readyRead slots instead and save the data part by part.
- How oft does onProgressChanged gets called? If it gets triggered for each percent your Graphic card should be able to do 100fps or even more...
-
I think the main issue is, that you are doing all the actual handling in the main thread, not in your worker thread. The cause is that you use slots on your subclassed QThread instance, and the QThread instance is in the main thread. So, the only thing in your example that runs in the worker thread, is the actual network handling (the QNetworkAccessManager). The rest in in the GUI thread.
Rule of thumb: don't subclass QThread, especially if you use signals and slots. Instead, use a vanilla QThread object, and move a worker object (derived from QObject) to the thread. The worker object then does all the work. QThread is meant only as a 'manager' of the thread.
-
[quote author="Andre" date="1348044626"]
Rule of thumb: don't subclass QThread, especially if you use signals and slots. Instead, use a vanilla QThread object, and move a worker object (derived from QObject) to the thread. The worker object then does all the work. QThread is meant only as a 'manager' of the thread.[/quote]Exactly what the article "How To Really, Truly Use QThreads; The Full Explanation":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ explains...
-
[quote author="AcerExtensa" date="1348044754"]
[quote author="Andre" date="1348044626"]
Rule of thumb: don't subclass QThread, especially if you use signals and slots. Instead, use a vanilla QThread object, and move a worker object (derived from QObject) to the thread. The worker object then does all the work. QThread is meant only as a 'manager' of the thread.[/quote]Exactly what the article "How To Really, Truly Use QThreads; The Full Explanation":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ explains...[/quote]
Just as many other articles do, including the (in)famous "You Are Doing It Wrong":http://blog.qt.digia.com/2010/06/17/youre-doing-it-wrong/ blog post, and the "extensive wiki article":/wiki/Threads_Events_QObjects right here on DevNet. Anyway, I was already writing the reply in the time you posted yours, so our replies got crossed.
Edit: Oh, and there is also the "online Qt documentation":/doc/qt-4.8/QThread.html where your truly left a docnote on this as well.
-
It was more for napajejenune.., than for you Andre. Just to force him to read article and get clue about QThread's behavior...