I have an application where items being added to collections from multiple threads. Randomly i get an
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread. at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
Now the collections are created in a class , the classes themselves are created on multiple threads.
Here is a class example
public class Example
{
public Example()
{
BindingOperations.EnableCollectionSynchronization(collection, COLLECTION_LOCK);
var defaultView = CollectionViewSource.GetDefaultView(collection);
defaultView.SortDescriptions.Add(new SortDescription("SomeProperty", ListSortDirection.Ascending));
if (defaultView is ICollectionViewLiveShaping liveShaping)
liveShaping.IsLiveSorting = true;
}
private readonly object COLLECTION_LOCK = new object();
private readonly ObservableCollection<object> collection = new ObservableCollection<object>();
public ObservableCollection<object> Collection
{
get
{
return collection;
}
}
private void AddItem(object item)
{
lock(COLLECTION_LOCK)
{
if(!Collection.Contains(item))
{
Collection.Add(item);
}
}
}
private void RemoveItem(object item)
{
lock (COLLECTION_LOCK)
{
if (Collection.Contains(item))
{
Collection.Remove(item);
}
}
}
}
I am using the BindingOperations.EnableCollectionSynchronization to allow cross thread operations and always use the specified lock to modify collection. Still the error comes up randomly.
I have also tried to use BindingOperations.AccessCollection when accessing the collection but the error still happens randomly.
The MS documentation states that ObservableCollection must be created on a UI thread? Can someone confirm that its the case?
Also you can notice that i get the default collection view CollectionViewSource.GetDefaultView(collection)
The collection view is also created on same thread and technically as i understand its the source of the problem.
I have tried to simulate adding from different threads by creating thousands of tasks and modifying the collection with no error happening BUT again randomly error pops up out of nowhere, i tested with both where collection was not bound and bound to UI.
Any ideas?
Stack trace
System.NotSupportedException: This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.RemoveItem(Int32 index)
at System.Collections.ObjectModel.Collection`1.Remove(T item)
at Manager.ViewModels.HostViewModelBase.RemoveUser(IUserMemberViewModel user)
The collection view flags are System.Windows.Data.CollectionView.CollectionViewFlags.ShouldProcessCollectionChanged | System.Windows.Data.CollectionView.CollectionViewFlags.IsCurrentBeforeFirst | System.Windows.Data.CollectionView.CollectionViewFlags.IsCurrentAfterLast | System.Windows.Data.CollectionView.CollectionViewFlags.IsDynamic | System.Windows.Data.CollectionView.CollectionViewFlags.AllowsCrossThreadChanges | System.Windows.Data.CollectionView.CollectionViewFlags.CachedIsEmpty
and AllowsCrossThreadChanges is true