Home > Uncategorized > Bulk loading in ObservableCollection.

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)
      base.OnCollectionChanged(e);
  }

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

    _suppressNotification = true;

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

Anyway, I hope this helps you out.

About these ads
  1. February 20, 2009 at 5:32 am

    Nice idea, Pete.

    • peteohanlon
      February 20, 2009 at 8:47 am

      Thanks very much. I’m glad you like it.

  2. Collin
    March 11, 2010 at 2:18 pm

    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);
    OnCollectionChanged(args);

    And then for removal use .Remove

  3. May 26, 2010 at 8:13 pm

    Now this is what I came here for tonight …

    cut-paste-thanks.

    Colin E.

  4. John Fairbanks
    September 21, 2010 at 10:00 pm

    Dude… you are awesome. Thanks so much.

  5. Qwe
    October 6, 2010 at 7:22 pm

    Super! Thanks!

  6. Qwe
    November 1, 2010 at 3:14 pm

    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…

  7. June 28, 2012 at 3:16 pm

    Perfect… just saw a performance bottleneck completely vanish. Thankyou!

  1. April 3, 2012 at 7:45 pm
  2. May 24, 2012 at 5:05 am

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

The Canny Coder

Java 8 Functional Programming with Lambda Expressions

pihole.org

Adventures in theoretical computer science, with your host, chaiguy1337

Confessions of a coder

Confessions of a WPF lover

WordPress.com

WordPress.com is the best place for your personal blog or business site.

Follow

Get every new post delivered to your Inbox.

Join 39 other followers

%d bloggers like this: