views:

1936

answers:

3

Time and time again I find myself having to write thread-safe versions of BindingList and ObservableCollection because, when bound to UI, these controls cannot be changed from multiple threads. What I'm trying to understand is why this is the case - is it a design fault or is this behavior intentional?

+15  A: 

The problem is designing a thread safe collection is not simple. Sure it's simple enough to design a collection which can be modified/read from multiple threads without corrupting state. But it's much more difficult to design a collection that is usable given that it's updated from multiple threads. Take the following code as an example.

if ( myCollection.Count > 0 ) {
  var x = myCollection[0];
}

Assume that myCollection is a thread safe collection where adds and updates are guaranteed not to corrupt state. This code is not therad safe and is a race condition.

Why? Even though myCollection is safe, there is no guarantee that a change does not occur between the two method calls to myCollection: namedly Count and the indexer. Another thread can come in and remove all elements between these calls.

This type of problem makes using a collection of this type quite frankly a nightmare. You can't ever let the return vtalue of one call influence a subsequent call on the collection.

EDIT

I expanded this discussion on a recent blog post: http://blogs.msdn.com/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx

JaredPar
I have the exact same problem. How do I use the Dispatcher or else to add an item to my BindingList from a background thread?
Kave
+3  A: 

To add a little to Jared's excellent answer: thread safety does not come for free. Many (most?) collections are only used within a single thread. Why should those collections have performance or functionality penalties to cope with the multi-threaded case?

Jon Skeet
Well, maybe I should rephrase it then: why doesn't the framework provide a ThreadSafeObservableCollection or some such?
Dmitri Nesteruk
That's a more reasonable question - but then Jared's answer kicks in. It really depends on what you mean by "thread-safe" - which is not a simple yes/no flag.
Jon Skeet
+1  A: 

If you want to go crazy - here's a ThreadedBindingList<T> that does notifications back on the UI thread automatically. However, it would still only be safe for one thread to be making updates etc at a time.

Marc Gravell
This implementation only marshals 'adds' to the sync context thread: does not protect against an number of other race conditions and/or collection modified errors when enumerating the list.
piers7