Merging a list into an ObservableCollection is throwing too many Property change notifications

297 views Asked by At

I'm working on a small standalone system in C# .Net running on an embedded processor, we're using GTK for the UI and storing the data in a MySql database. Database access is done through our own data access layer and we use our own translation layer to convert from Model types into DAO types.

For accessing data in the system we have a DataStore class for each type, this class holds an index list (Just Name and ID, we do lazy loading) of all active items and this is currently contained in an ObservableCollection which the UI binds to.

When we update this list we read the indexes from the DB, convert the items from DaoTypes to Model types and then enter them into the ObservableCollection.

The guy in charge of the UIs has just raised a Jira ticket saying that adding to the ObservableCollection this way is raising a Notify Property Changed event for each item we enter and that this makes it unusable for his UI.

I'm not sure if this is an issue with the way I do things by using the ObservableCollection or if the UI should be able to handle this level of load, we're not talking loads of items, maybe 20-50 maximum.

I tried maintaining this list on the fly, adding and removing items manually rather than loading the list each time but loading the list fresh is much more reliable.

  • Should we be able to expect the UI can handle these Property Changed Notifications?
  • Is there a more efficient way than using the ObservableCollection like this?
1

There are 1 answers

0
Peter Duniho On

Without more specifics, or e.g. a good, minimal, complete code example that clearly illustrates the question, it's impossible to provide advice with any real confidence.

That said:

Should we be able to expect the UI can handle these Property Changed Notifications?

That depends on the UI and your platform. For a desktop computer, 50 insertions into a UI object is nothing. For an embedded platform, it could be an issue. It could be disastrous for a UI written naively and targeting an e-paper display (i.e. a display with a painfully slow refresh rate).

Note that if you did want to push this issue back onto the UI code, and the UI is for some reason unable to process 50 separate updates, it could instead keep a timer and update the UI after the collection has been modified only when no modifications have occurred for some time (e.g. 100 ms…or whatever delay would be appropriate in your scenario, depending e.g. on the latency of whatever framework you're using, the latency of your own code, etc.).

Is there a more efficient way than using the ObservableCollection like this?

The whole point of ObservableCollection<T> is so that the consumers of the collection can be notified of changes to the collection as they occur. This is common and very useful in e.g. the WPF scenario. There is no way to disable this behavior.

Note that if you are not necessarily tied to ObservableCollection<T> per se, you could use instead the BindingList<T> class. That has a RaiseListChangedEvents property, which you can set to false to disable notification.

But even if ObservableCollection<T> had such a feature, or you were able to switch to BindingList<T>, then you would have a different problem: how to signal to the UI that you are done adding elements to the list. And since you would have to solve that, you could just implement that anyway and just use any collection type (since such a mechanism should work with any collection type).

The UI is binding to the ObservableCollection

What binding implementation are you using? Something built into .NET? If so, which one? Something else?

Note that any of the .NET binding implementations would correctly handle the scenario where the entire collection is replaced with another, whether that happens by setting a UI property to the collection directly, or that UI property is itself bound to a bindable property (e.g. supported by XXXChanged, INotifyPropertyChanged, or is an actual DependencyProperty in e.g. WPF or Winrt).

In other words, if you are using a binding implementation with "reasonable" behavior, then the suggestion to just populate a whole new list and reset the bound collection to that new list should work fine. When the UI sees the collection object reference value change, it can rebuild the UI accordingly based on the new collection object.


I will point out that since you seem to recognize the value in reliability on your end with respect to reloading a new collection vs. maintaining a single collection as edits occur, I would think you would similarly recognize the value in doing so with respect to the UI code.

I.e. even if there weren't a performance problem, if you're going to rebuild the list yourself anyway based on the DB contents, doesn't it make sense to just give the UI that whole new collection as well? It's certainly easier, and any theoretical performance gain that might be had by updating the UI as insertions and deletions occur is lost by your layer, which apparently groups such edits into a single large-scale update operation.