How to add thousands of items to a binded collection without locking GUI

steveg89 picture steveg89 · Aug 14, 2012 · Viewed 13.6k times · Source

I have a setup where potentially thousands of items (think 3000-5000) will be added to an ObservableCollection that is binded to some visual interface. Currently, the process of adding them is quite slow (approx. 4 seconds/1000 items), and of course the GUI is unresponsive during that time. What is a good method to handle moving that many items at once into a collection without worrying about the system locking up? I've looked at DispatcherTimer but I'm not sure if it will provide everything I need it to.

Another question - Is there something I can do to speed up the creation of these objects so that it doesn't take so long to add them to the collection? Currently I use them like so: Collection.Add(new Item(<params>)) Would generating the items beforehand, in a background thread probably, decrease the time it takes to add them by a noticeable amount?

Edit: Virtualization is not possible. The requirements specify a WrapPanel look, so the display is actually a ListBox which has a templated ItemsPanel

Edit2: According to the stopwatch, the bottleneck is actually putting items into my ObservableCollection. I will try changing that collection type and doing my own notification to see if that speeds it up substantially.

Edit3: So the answer is in one place - I solved this issue (with help from below) by creating a class which inherits from ObservableCollection. This class did two things - expose a method to add collections at one time, and added the ability to suppress the CollectionChanged Event. With these changes the time it takes to add 3000 items is roughly .4 seconds (97% improvement). This link details the implementation of these changes.

Answer

David Anderson picture David Anderson · Aug 14, 2012

WPF Binding supports concurrency for this reason. Try setting Binding.IsAsync to true. In addition.

  • Don't use ObservableCollection<T>, it is slow for this because each time an item is added it raises events. Use something faster like List<T> and raise your property change notification after all your items are added.
  • Pre-create your items in a background thread, then push them into your collection.
  • Check other parts of code involved to see if there is bloat, and trim.