0

I have application in WPF and I want to clear ObservableCollection when setter is set from another thread.

This is setter:

public List<Model.MasterReview> SelectedMasterReviews
        {
            get { return selectedMasterReviews; }
            set
            {
                selectedChildReview = null;
                selectedMasterReviews = value;

                Application.Current.Dispatcher.Invoke((Action)delegate
                {
                    GetChildReviews();
                });
            }
        }


private void GetChildReviews()
        {
            Application.Current.Dispatcher.Invoke((Action)delegate
            {
                ChildReviews.Clear();
            });
}

And I get error:

    This type of CollectionView does not support changes to its SourceCollection from a thread
 different from the Dispatcher thread

This code give me the same error:

var uiContext = SynchronizationContext.Current;
uiContext.Send(x => ChildReviews.Clear(), null);
Robert
  • 2,571
  • 10
  • 63
  • 95
  • 1
    Are there several dispatchers invoved? Please see [this](https://stackoverflow.com/a/53100050/7252182) answer. – mm8 Jun 03 '20 at 14:32
  • On which thread did you instantiate your Observable Collection? – Norbert Forgacs Jun 03 '20 at 15:06
  • Yes I had this method BindingOperations.EnableCollectionSynchronization(ChildReviews, _lock) – Robert Jun 03 '20 at 16:14
  • @mm8 Yes there are several dispachers. And the error occurs when ChildReviews is Clear in the dispatcher in another place and then here in above code. When I call only above code, it works – Robert Jun 03 '20 at 16:29
  • 1
    I've created this little helper library to reduce the pain of working with observable collections from multiple threads: https://www.nuget.org/packages/Divis.AsyncObservableCollection/ It basically works by initializing the collection with a delegate that runs all the operations through a dispatcher, so you don't have to worry about which thread you're calling it from. I know it's probably not the cleanest solution but it works just fine in all my WPF and Xamarin.Forms apps. – Michal Diviš Jun 04 '20 at 06:00
  • 1
    @Robert: You "had" `BindingOperations.EnableCollectionSynchronization`? And it didn't work or what? You can only clear the collection using the dispatcher that actually owns the data bound view which is obviously not `Application.Current.Dispatcher` in your case. Please provide a [repo](https://stackoverflow.com/help/minimal-reproducible-example) of your issue for further help. – mm8 Jun 04 '20 at 12:35
  • @MichalDiviš thanks for help – Robert Jun 09 '20 at 12:54

1 Answers1

0

I've resolve this problem. First time ChildReviews was cleared in another thread:

   Task.Run(() => Application.Current.Dispatcher.Invoke((Action)delegate
                {
                    GetChildReviews();
                }); )

and then in another dispather:

Application.Current.Dispatcher.Invoke((Action)delegate
{
    GetChildReviews();
});

I had to remove Task.Run() and now it works

Robert
  • 2,571
  • 10
  • 63
  • 95