I have a MVVM application. I have ObservableCollections that hold my models. If OnCollectionChanged is fired and we have "Add" event then I insert the item into my data base.

I have a function that reads data from a file, creates models and adds them to their collection. Because of relations in my database I have to add them in certain order.

Example:

  • Post (post id, post number, post town)
  • Gender (gender id, gender)
  • Person (name, last name, post id, gender id)

So I would first make Post models, add them to ObservableCollection, which then fires OnCollectionChanged which fires insert. Then I would add Gender model and then Person model. So first all the OnCollectionChanged events of ObservableCollection<Post> would get fired, then OnCollectionChanged events of ObservableCollection<Gender> and then OnCollectionChanged events of ObservableCollection<Person>.

I want to move this import to background. What I am using is an asynchronous command that makes locks, sets BindingOperations.EnableCollectionSynchronization and runs Task.Run. Inside the task I call one method that reads the file and returns data in an object and a second void method which inserts data in the ObservableCollections using lock.

The problem I have is that after the thread finishes the main thread fires the OnCollectionChanged events alternately:

  • One Post model is added -> fires OnCollectionChanged
  • One Gender model is added -> fires OnCollectionChanged
  • One Person is added -> fires OnCollectionChanged
  • One Post model is added
  • One Gender model is added
  • One Person is added
  • etc...

This causes errors as it tries to insert Person model whose Gender model and Post model have not yet been inserted. Is this expected behaviour? Can I change the order of these events firing?

1

There are 1 best solutions below

1
Alex On

Instead of adding all at the same time, you can put the adding into one task or have the tasks start in order.

Task.Run(() => 
{
    AddPosts();
    AddGenders();
    AddPersons();
}

This way it is asynchronous but in the correct order.