After floundering a bit with the WPF Dispatcher I've come up with a simple way to make sure an event handler executes on the UI thread without paying the overhead of always invoking a delegate.
void someEvent_Handler(object sender, SomeEventEventArgs e)
// do work on UI thread
// or BeginInvoke()
this.Dispatcher.Invoke(new Action<object, SomeEventEventArgs>(someEvent_Handler),
This has the benefit (for me at least) of being very easy to remember. Hook up the event handler and then if there's a chance it could be called from a different thread wrap it using the pattern above. It's easier to read than an anonymous delegate and much faster than defining a specific delegate for the event in question.
I haven't tested the various methods to see which is the fastest yet… will get round to this at some point.