(There's a tiny bit of history to this question, please bear with me)
In this question, I talked about the possibility of centralising the 'cross thread' hocus-pocus that is required for updating the GUI like so:
//Utility to avoid boiler-plate InvokeRequired code
//Usage: SafeInvoker.Invoke(myCtrl, () => myCtrl.Enabled = false);
public static void Invoke(Control ctrl, Action cmd)
{
if (ctrl.InvokeRequired)
ctrl.BeginInvoke(new MethodInvoker(cmd));
else
cmd();
}
Last week, mulling over the fact that this always happens (in my code) when handling an event, and partly inspired by Dustin Campbell's event extension method, I cooked up this:
//Utility to avoid boiler-plate SafeInvoker.Invoke code
//Usage obj.EventRaised += obj_EventRaised.OnGUIThread(controlreference);
public static EventHandler OnGUIThread(this EventHandler h, Control ctrl)
{
// lambda expressions are not syntactic sugar, they are syntactic crack!
return (s, e) => SafeInvoker.Invoke(ctrl, () => h(s, e));
}
The thing that bugs me here is always having to have a control to hand. As far as I know, there is only one GUI thread, so any control would do here.
I got to wondering about creating a 'GUIContext' singleton and throwing it a reference to my main form when the application starts up, then accessing that from my extension method, thus removing the need for the ctrl parameter.
Is this a bad idea, and if so, why? Is there a better way to do it? I know that in Rx there is a notion of Context, but I'm not aware of anything equivalent in vanilla WinForms. I can imagine there might be a problem if I try to update a control that is not yet handled (but in that case I'm screwed anyway).