|
Dave Kreskowiak wrote: That's because the UI thread has to handle adding those items to the ListView. it cannot be done from another thread because you can only maniplute a control on the thread that created it.
You can, however, add each item tot he ListView, one a few at time, from a background thread, by Invoking a method on the UI thread to add just a few items at a time.
What about using a delegate on the background worker thread? This worked for me.
' Because we run our routine that gets the selected class's properties on a background thread using the
' BackgroundWorker component, we can't update our listview directly using this thread, if we try, we get
' a cross-threading exception; our listview was created on the program's main thread and can't be changed
' directly by our background thread.
' To get round this little problem, we create delegate routines and then call the listview control's
' invoke method which uses the delegated routine to update the listview control on the main thread.
Private Delegate Sub AddItem(ByVal lv As ListView, ByVal lvi As ListViewItem)
Private Shared Sub AddListViewItem(ByVal listViewCtrl As ListView, ByVal lvi As ListViewItem)
listViewCtrl.Items.Add(lvi)
End Sub
listViewCtrl.Invoke(New AddItem(AddressOf AddListViewItem), New Object() {listViewCtrl, lvGroupItem})
I'm too lazy to Google it for you.
|
|
|
|
|
A delegate doesn't get around the thread/control problem. It just sets up a parameter for the Invoke call so the AddItem call gets made on the UI thread and not the background thread.
|
|
|
|
|
Change your design and use VirtualMode[^] to allow fast drawing of the ListView irrespective of where in the view you are positioned.
I must get a clever new signature for 2011.
|
|
|
|
|
ok, I may try that in the end
Чесноков
|
|
|
|
|
Hi,
here are some ideas for you:
1. having thousands of items in any Control does not make for a good user interface.
2. list oriented Controls will relayout and/or repaint themselves after every addition. it is wise to use AddRange rather than Add, and sometimes surround the entire operation with SuspendLayout/ResumeLayout.
3. if obtaining the items takes a while, it often helps to build a collection of items to be added to a list Control in a generic list, then add the list's content to the Control. The former can be performed on any thread, the latter obviously needs to be executed by the main thread.
4. some Controls have a "virtual mode" where one only needs to provide items when they become visible.
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
modified on Monday, January 31, 2011 10:26 AM
|
|
|
|
|
1. log events with time column are easy to scroll
2. I tried to hide listview during items addition and then show it again, that increased performance, I will try yours methods
3. no, it does not, objects are already in the generic list with public methods e.g. time, message, keyword etc... the list view is in details view with columns to each field
4. that is not agreeble compared to 2.
Чесноков
|
|
|
|
|
For logging I recommend a ListBox, it will easily handle thousands of lines per second. See here[^].
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
I need to display log events which are already collected in a generic list.
There are thousands of them, I'd like to explore the limits.
ListBox does not contain columns to show specific fields
Чесноков
|
|
|
|
|
Luc Pattyn wrote: . it is wise to use AddRange rather than Add, and
It will need to create a list of ListViewItems. Will it be faster than reporting from background worker item by item?
Чесноков
|
|
|
|
|
Luc Pattyn wrote: sometimes surround the entire operation with SuspendLayout/ResumeLayout
that is significantly slower than hiding the control
Чесноков
|
|
|
|
|
|
Which is exactly the answer I gave!
I must get a clever new signature for 2011.
|
|
|
|
|
|
|
Sorry, but this is not something I have ever used. I would suggest you open a new question so others will see it.
I must get a clever new signature for 2011.
|
|
|
|
|
|
|
Great, thanks, virtual mode is of value to handle large lists especially with large icons.
I will use it from now for those purpouses.
However I presume I will not be able to use virtual view for log event because the list with those events is not static.
There are many threads which use global logger class to report events. They are stored in a queue and once queue limit exceeds some constant 100,000 previous one is dequeued.
Log event addition is safe with lock.
It is possible that in virtual list view between RetrieveVirtualItem() calls threads may report dozens of new events, queue will move and it will end up of showing the same or odd events several times.
Чесноков
|
|
|
|
|
|
|
No you missed the point. No one was telling you they couldn't handle it, or that the controls could not support it. They have been telling you it is not a good design. And using the argument that Microsoft does it is not valid. The Event Viewer and such controls are written specifically for high performance situation in C++. You are not doing that are you?
I know the language. I've read a book. - _Madmatt
|
|
|
|
|
this entire thread got way too much attention...
do or do not, there is no try
|
|
|
|
|
because the topic is a challenge to display 100,000 in as little time as possible, and to find a user who may process them all
Чесноков
|
|
|
|
|
The common way is to load items which are currently visible (plus some more for a buffer) and continue loading items on demand as user scrolls the list down.
|
|
|
|
|
Preload entries for viewable area and maybe a little around, then load entries only when they should be shown. Cannot specify more concrete, haven't programmed for windows for years. NEVER ever do progress bars for filling controls, this nerves a lot especially if you clicked the wrong control, always use lazy loading. Java AWT is particularly good designed for this approach
|
|
|
|