My program do the "heavy" task (searching files and finding a signature) on a separated开发者_StackOverflow thread. Every task uses PostMessage to call a procedure for adding a record into a ListView.
The problem is when ListView (often) displays many records, my window will freeze. It seems my program is screaming to request Application.ProcessMessages. Only the Progressbar is still moving. After the operation has finished, everything back to normal.
If I remove the operation for adding record, the operation of my program will run smoothly.
Do you have any idea?
We once hit the limit of how many messages can be posted to the message queue. Most likely you are hitting this limit as well.
From MSDN
There is a limit of 10,000 posted messages per message queue. This limit should be sufficiently large. If your application exceeds the limit, it should be redesigned to avoid consuming so many system resources.
From The Best Synchronization is No Synchronization
The problem with PostMessage to the main GUI thread is that you can "saturate" the main GUI message pump, and interfere with WM_TIMER and WM_PAINT messages (these messages are only dispatched if the message queue is empty, and PostMessage means that the queue might never be empty. In addition, there is a nominal limit of 10,000 messages in the input queue; after that, PostMessage will discard the message and return FALSE. In addition, even if the 10,000 limit is not hit, even a few hundred messages can mean that the user sees poor response to keyboard and mouse input, an unacceptable situation.
If you work with many items, it might be worth to change the overall structure of your program.
Instead of filling the list view, try filling some other data structure and then make another thread make the windows updates and use SendMessage
. That way your worker threads are not stalled and you don't flood your message queue. On the other hand this would require a lot more synchronizing between the threads.
Another way would be to use some control with virtual items, such as VirtualTreeview (which can be configured to behave like a list view) That way you can fill your backing data structure and the control asks for the data as soon as an item is scrolled into view. Because even with millions of items, only a few are visible at a time, this might give you a huge boost in speed, because filling the control now is only a matter of setting the total number of items.
You should consider using a virtual grid control, like the ExGridView from roman mochalov, or Mike Lishke's very popular Virtual Tree View (Delphi Gems). When new content arrives, merely set a flag, and then decide how often you want to refresh the screen, and refresh asynchronously, but not once per new item that comes in.
One refresh per 200 mSec will be all most users can stand to see, anyways.
精彩评论