Using BindingOperations.EnableCollectionSynchronization
All the examples I've seen on Stack Overflow for this get it wrong. You must lock the collection when modifying it from another thread.
On dispatcher (UI) thread:
_itemsLock = new object();
Items = new ObservableCollection<Item>();
BindingOperations.EnableCollectionSynchronization(Items, _itemsLock);
Then from another thread:
lock (_itemsLock)
{
// Once locked, you can manipulate the collection safely from another thread
Items.Add(new Item());
Items.RemoveAt(0);
}
More information in this article: http://10rem.net/blog/2012/01/20/wpf-45-cross-thread-collection-synchronization-redux
How does EnableCollectionSynchronization work?
You should synchronize all access to the collection using the same lock, i.e. you should lock around the call to Add
:
lock (itemsLock)
items.Add("foo");
The documentation is pretty clear on this:
To use a collection on multiple threads, one of which is the UI thread that owns the
ItemsControl
, an application has the following responsibilities:
- Choose a synchronization mechanism.
- Synchronize all access from the application to the collection using that mechanism.
- Call
EnableCollectionSynchronization
to inform WPF of the mechanism. - ...
How does BindingOperations.EnableCollectionSynchronization work, and how can you wrap it?
But how and why?
Because EnableCollectionSynchronization
enables the CollectionView
that sits in between the source collection and the ItemsControl
to participate in synchronized access. So you need to call it on the actual INotifyCollectionChanged
that you bind to in the view.
CollectionViewSource.GetDefaultView(Collection)
is not equal to CollectionViewSource.GetDefaultView(this)
. In fact, Collection
should be a private field of ThreadedObservableCollection<T>
because it's an implementation detail. The view and WPF binds to an instance of ThreadedObservableCollection<T>
and knows nothing about the internal ObservableCollection<T>
.
Related Topics
How to Compile a C# File with Roslyn Programmatically
Accelerating Bitmap Grayscale Conversion, Is Openmp an Option in C#
When to Use Properties Instead of Functions
Convert an Object to an Xml String
Deserializing Heterogenous JSON Array into Covariant List<> Using JSON.Net
Programmatically Get Summary Comments at Runtime
Is [Callermembername] Slow Compared to Alternatives When Implementing Inotifypropertychanged
Convert Transparent Png to Jpg with Non-Black Background Color
Accessing All the Nodes in Treeview Control
Random Errors Using Wait for Element Clickable Method in Selenium
Testinitialize VS Classinitialize
Linq to SQL Where Clause Optional Criteria
How to Send an Email in .Net According to New Security Policies
Casting Object to Int Throws Invalidcastexception in C#