Reputation: 1504
I have been struggling to grasp this concept and even after many experiments I still can't figure out what the best practise is with ObservableCollections in WPF and using BindingOperations.EnableCollectionSynchronization.
If I have a viewmodel with an observable collection and I enable collection sync on it using a lock as shown below:
m_obsverableCollection = new ObservableCollection<..>;
BindingOperations.EnableCollectionSynchronization(m_obsverableCollection,
m_obsverableCollectionLock);
Does that mean that every modification and enumeration over that observable collection will:
When using BindingOperations.EnableCollectionSynchronization, will I ever need to do any kind of locking explicitly?
The problem which spawned all this is that even after using BindingOperations.EnableCollectionSynchronization and locking items using the same lock I passed into that method, very occasionally I get the "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread." exception
Upvotes: 13
Views: 6284
Reputation: 1504
We finally got to the bottom of it:
We have to enable CollectionSynchronization on the dispatcher:
Application.Current.Dispatcher.BeginInvoke(new Action(()=>
{
BindingOperations.EnableCollectionSynchronization(m_obsverableCollection, m_observableCollectionLock);
}));
Then everytime any other thread wants to access the observable you can simply:
lock (m_observableCollectionLock)
m_observableCollection.Add(...)
Upvotes: 13
Reputation: 15794
I haven't used that particular syntax, but whenever I need to update an ObservableCollection
from a background thread, I follow this pattern:
// i just typed this off the top of my head, so be forewarned... :)
lock(someLockingObj)
{
Application.Current.Dispatcher.BeginInvoke(new Action(()=>
{
... update here....
}));
}
Usually the error that you've encountered occurs when a bg thread is trying to update the ObservableCollection
directly, without the Dispatcher.BeginInvoke
(or even Invoke
would work too, most of the times, IMHO).
Upvotes: 2