I need a thread-safe (concurrent) version of ObservableCollection in Silverlight 5. I’m struggling to find a way to create one given the lack of multi-threading support in SL5 (no ReaderWriterLock, no Collections.Concurrent to speak of, etc).
I need the collection to support UI binding while being updated by another thread. It is not acceptable for my to dispatch all of my updates to the UI thread when the process runs in the background. Ideally, the background process is free to update the collection as needed and the UI receives notifications as changes occur. This is possible with .NET 4 and I’ve found ways to accomplish this for WPF but nothing for SL. I can’t use the WPF examples because they rely on ReaderWriterLock which, AFAIK, is not present in SL5.
Any direction and/or examples is appreciated.
UPDATE
Following the asynchronous communication pattern used (required) in Silverlight, the ‘callback’ method, or handler, runs on a different thread. Using the TPL (as we do), this is the task’s Continuation.
Because this code runs on a different thread, any statements that affect the ObservableCollection have to be marshalled back to the UI thread. This means that the process logic and time are now consuming the resources of the UI thread.
The point of the concurrent collections in .NET is to allow producers and consumers to run in different threads yet seamlessly work with the shared data in the collection. The ‘producers’ in a SL client application will be the async callback or task continuation with the ‘consumers’ being the UI which is bound to the collection.
I also ran into this problem repeatedly, which caused me to go down the same road you’re looking at. There is a library that has helped me immensely with this task:
http://ch.codeplex.com/
I’ve implemented my own ConcurrentObservableCollection using the TinyReaderWriterLock and implementing IList, INotifyCollectionChanged, INotifyPropertyChanged
I used this blog post as a starting point.
http://www.deanchalk.me.uk/post/Thread-Safe-Dispatcher-Safe-Observable-Collection-for-WPF.aspx
In my version I allow all calls to execute on the calling thread and only marshal the INotifyCollectionChanged and INotifyPropertyChanged calls back to the UI Thread like this:
where
and
This has worked well for me. There is a small performance hit involved with the locking, but it’s not significant for most uses.