It’s about time now for another programming post. (I noticed a little while ago that I appear to be maintaining a “two posts other, one post programming” pattern. This was unintentional at first, but once I noticed I figured I might as well keep it up. We’ll see how long it lasts before I get bored.) And this one’s going to be a long one.
I’ve been experimenting a bit in recent months with WPF, and in particular trying to do things the “WPF way” by using data binding to tie domain objects to the UI rather than writing code. This all works fairly well once you get the basic concepts down, but there’s one gaping hole in the framework: while it can cope with property changes occurring across threads, it can’t cope with collection changes across threads. This means that if you’re binding to a collection (to display a list of items somewhere), then that collection can only be modified on the UI thread, not any other thread. If you break this rule, then things may seem to work for a while, but you’ll eventually either get a simple exception (a NotSupportedException saying “This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.”) or a weirder exception (such as an IndexOutOfRangeException from deep within the internals of the framework).
But sometimes (eg. for performance reasons), you really do need to update that collection from a different thread. You might think you can get away with just making the collection synchronised (wrapping every operation in a lock), but there are two problems with that. First, you would have to synchronise enumeration operations too, which you can’t do from within the collection class — and since the WPF code is written assuming a single thread, it’s unlikely it will be doing the synchronisation itself. Second, from some of the weird messages it produces, it’s clear that after getting a “collection changed” notification the framework will go and access the collection to retrieve additional info — and by the time it does that the collection may have changed again, meaning it will be accessing the wrong items and getting itself horribly confused.
Continue reading Multithreaded Collections and WPF



Recent Comments