Yes, you should ALWAYS make sure that you're changing UI objects on the UI thread. And I believe you don't really have a choice in .Net 2.0. It would throw an exception otherwise.

But seeing the various syntax for doing so, I realize that C# utterly failed on making the intention of the act understandable.

Bleah
main.Invoke(new MethodInvoker(delegate() { Text = "Keyboard acquired"; }));

Bleah bleah
Public Sub ReadKeyboard()
        If Me.InvokeRequired Then
            Dim x As Action = AddressOf ReadKeyboard
            Me.Invoke(x)
        Else
            me.Text = "Keyboard acquired"
        End If
End Sub

Bleah bleah bleah
public static void InvokeOnUIThread( this Control myControl, Action action );
public static void InvokeOnUIThread<T>( this Control myControl, Action<T> action, T parameter );
this.InvokeOnUIThread( () => myControl.Text = "Keyboard acquired" );

How about just automatically synchronize UI access like Silverlight?