First...I feel your pain. The Ui thread restriction can be a pain...
Why can't you update a Ui Element from
a thread other than the one it was
created on ?
My question is, why there is such an
exception?
Well in a nutshell, history. Windows has been around a while and the way some parts of the Gui work are embedded in technologies such as COM and the like....so changing it is not trivial...would be very easy to break something. There are many other issues I'm sure...but somebody smarter than me would need to explain them. I believe the WPF team really wanted to remove this restriction and they worked at it pretty hard...in the end I think the number of core OS changes need was unworkable...so they moved on....rats.
Why wasn't it possible to allow
collection updates from any thread?
Is was and is possible... Making something thread-safe always costs some in performance and add complexity. In most cases the application doesn't call for multi thread access. It is important to understand that, for the most part, Microsoft plays by the same rules we do and the same restrictions. If they had made the ObservableCollection thread-safe ...they would have used the same tools we have...locks, monitors, etc. They cannot break the Ui thread rule any more than we can...no magic...same rules.
I know there are workarounds, so my
question is not how to avoid the "This
type of CollectionView does not
support changes to its
SourceCollection from a thread
different from the Dispatcher thread"
exception.
There are no workarounds...There is nothing to workaround. The ObservableCollection is broken..it is just not thread-safe. You must make it, or access to it, thread-safe. This is the same for anything that is not thread-safe...if you need it to be thread-safe then make it so. If you are using threads then you know about locks and such...use them..that is what they are for.
...block UI update when
ObservableCollection is changed from
other threads.... it will always work,
at least if locks are used
properly....
If locks are used properly...Exactly ! Again, Microsoft could have put these locks in but they didn't and for very good reasons. You can put the locks in. Or you use other tactics that will give you thread-safe access....lots of options.
The Task Parallel Library in .net4.0 provides some new tools for solving these problems. Being able to set a context for a task or a thread is particularly useful...
// get the Ui thread context
_uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Action DoInBackground = new Action(() =>
{
/*...In the background...
...process some data for an ObservableCollection...*/
});
Action DoOnUiThread = new Action(() =>
{
/*...On the UI thread...
...read/write data to an ObservableCollection...*/
});
// start the background task
var t1 = Task.Factory.StartNew(() => DoInBackground());
// when t1 is done run t1..on the Ui thread.
var t2 = t1.ContinueWith(t => DoOnUiThread(), _uiScheduler);
Don't think about the thread affinity requirements of Ui Elements as something to work around....it is just the way it works.
C# and .Net have many tools that you can use that make threading a little less of a nightmare. Use them..they can be fun.
I'm going for a smoke.