Bulk loading in ObservableCollection.

Today, in Code Project, a poster asked a question about the best way to insert multiple items in ObservableCollection as a bulk insert. The poster wondered why it was taking so long to add records doing an Add for each item in the collection. Now, in several of the .NET collections, there’s an AddRange method that allows you to add multiple items in “one hit”, so why isn’t there one in ObservableCollection? Well, part of the reason seems to be that this goes outside what you would use an ObservableCollection for. In other words, it’s not aimed at adding multiple items, it’s aimed at monitoring small changes.

So, what makes ObservableCollection unsuitable for large scale inserts? Well, the primary reason lies in the fact that an Add operation fires off a CollectionChanged event – it’s this event that is contributing to a large part of the slowdown. Fortunately, there is a way to get round this limitation, and it lies in the wonderful world of inheritance.

The following class is based on an ObservableCollection, and adds a new method (AddRange) that adds the items in quickly by suppressing the CollectionChanged event until the load has finished. (It doesn’t implement a RemoveRange method, but it would follow a similar pattern). Simple tests showed that this ran 3 times faster than the ordinary methods.

public class RangeObservableCollection<T> : ObservableCollection<T>
  private bool _suppressNotification = false;

  protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    if (!_suppressNotification)

  public void AddRange(IEnumerable<T> list)
    if (list == null)
      throw new ArgumentNullException("list");

    _suppressNotification = true;

    foreach (T item in list)
    _suppressNotification = false;
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

Anyway, I hope this helps you out.

10 thoughts on “Bulk loading in ObservableCollection.

  1. Collin

    if the OnCollectionChanged using a different NotifyCollectionChangedEventArgs you can still observe the collection changeing. Using the constuctor of only passing NotifyCollectionChangeAction.Reset will not allow listeners to observe changes.

    I suggest using

    NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list);

    And then for removal use .Remove

  2. Qwe

    My datagrid 50*4 is binding on ObservableCollection. Changes occur frequently and over and over.

    I used OnCollectionChanged, and saw a heavy load on the CPU. I tried use OnCollectionChanged from this topic, and saw a same heavy load on the CPU.
    I did not understand the reason. I tried use OnPropertyChanged, and heavy load on the CPU disappeared.

    To understand what is the reason I tried to modify the elements (not Clear and Add), but used the event OnCollectionChanged, which is called once, after all the changes. I get same – a heavy load on the CPU. So, I think, OnCollectionChanged – very slowly. Even if you do not use to redraw the elements, its use require much more CPU resourses…

  3. Pingback: Adding many entries to an Observable collection in a performance friendly way « Binary sculpting

  4. Pingback: Can I somehow temporarily disable WPF data binding changes? | PHP Developer Resource

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s