Have I missed something with WPF (and Windows Forms before it) in regards to the need to write a lot of repetitive code when developing multi-threaded applications. Every UI
Don't forget lambdas:
int myParam = 5;
Dispatcher.BeginInvoke((Action)(() => SomeMethod(myParam)));
There is also a hidden intellisense method on the dispatcher:
if(Dispatcher.CheckAccess())
DoSomething();
Well you can certainly make it simpler than that. For one thing you don't need all your own separate delegate types - you can use the built-in Func<...>
and Action<...>
delegates if you're using .NET 3.5, and if you're not you can declare them yourself and then use them generically.
The other thing you might consider is writing a helper method (as an extension method, if you're using C# 3) and then use anonymous methods (or lambda expressions):
internal static void SetElementIsEnabled(UIElement element, bool isEnabled)
{
InvokeIfNecessary(element, delegate
{
element.IsEnabled = isEnabled;
});
}
The helper method would be:
public static void InvokeIfNecessary(UIElement element, MethodInvoker action)
{
if (element.Dispatcher.Thread != Thread.CurrentThread)
{
element.Dispatcher.Invoke(DispatcherPriority.Normal, action);
}
else
{
action();
}
}
(You should probably also include a BeginInvoke
equivalent. I generally prefer BeginInvoke
unless I need the rendezvous.)
Simply put, for performance reasons. Why should every GUI app have to take on the performance implications of marshalling code when only those that are multi-threaded require it?
Further, you can design your app to have less cross thread chatter, so that less invoking is necessary.
Also, your code is not particularly efficient. a better approach is:
if ( InvokeRequired ) {
Invoke(new MethodInvoker(this.Function));
} else {
// do code
}
EDIT: I guess my code is more for Windows Forms while yours is for WPF, but the purpose is the same. Windows requires that all control updates occur on the thread that created the control due to thread local storage issues. And this is just not something that should be there for all uses.