0

Should I use the dispatcher object if I want to update ObservableCollection on the worker or background thread?

Then why does this work:

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        for (int i = 0; i < 10000000; i++)
        {
            Data.Add("1");
        }


        Task.Run(() =>
        {
            Data.Clear();
        });
    }

    public ObservableCollection<string> Data
    {
        get => _data;
        set
        {
            _data = value;

            OnPropertyChanged();
        }
    }

    private ObservableCollection<string> _data = new ObservableCollection<string>();

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

But this code throws an exception (at Data.Clear();): System.NotSupportedException: 'This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.'

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        for (int i = 0; i < 10000000; i++)
        {
            Data.Add("1");
        }


        Task.Run(() =>
        {
            Data.Clear();
        });
    }

    public ObservableCollection<string> Data
    {
        get => _data;
        set
        {
            _data = value;

            OnPropertyChanged();
        }
    }

    private ObservableCollection<string> _data = new ObservableCollection<string>();

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

In the first example we Clear ObservableCollection from the NON UI Thread as well as in the second. But the iterations count was lower. Can anyone explain the problem? I just want to add and clear items in the Collection.

VjBodkia
  • 1
  • 1
  • 1
    `But this code throws an exception:`, can you please include these details? – Trevor Mar 09 '22 at 17:54
  • 1
    Welcome to Stack Overflow! To give you a great answer, it might help us if you have a glance at [ask] if you haven't already. It might be also useful if you could provide a [mcve]. – Mat Mar 09 '22 at 18:04
  • Not necessarily but the `CollectionChanged` event have to be triggered on the UI thread. See this : [How do I update an ObservableCollection via a worker thread?](https://stackoverflow.com/questions/2091988/how-do-i-update-an-observablecollection-via-a-worker-thread) – Orace Mar 09 '22 at 18:28
  • 2
    You can use `ObservableCollection` from a background thread but only under certain restrictions. You must guard all inserts/removals with some sort of synchronization object and the `lock` statement. And you must call `BindingOperations.EnableCollectionSynchronization`, passing that same lock object in the call – Joe Mar 09 '22 at 18:29

0 Answers0