If the application is designed to be multithreaded, then cross-threading can occur and thus you need to check for it using InvokeRequired, and either have the method you are calling re-Invoke() itself on the UI thread, or throw an exception that will indicate code is being used improperly. Keep in mind that InvokeRequired will be false in certain circumstances (mainly when the window doesn't have a handle or is being/has been disposed); the best way to prevent these circumstances is to not start threads earlier in the window initialization process than the Load() event handler, and to handle the Closing() event by cancelling background threads created by the window and waiting for them to close.
If the application is not multithreaded (you are not setting up BackgroundWorkers, TPL operations, BeginInvoke()ing delegates or Start()ing threads), then it's not necessary. However, calls to InvokeRequired are pretty cheap (the logic behind it is basically a check that the WinAPI functions GetThreadId and GetWindowThreadProcessId return the same value), so if you anticipate the program being restructured to be multithreaded, the following patterns for called methods are simple enough to implement:
//no return value, no parameters; ShowWindow(), HideWindow(), etc
//Understand that many built-in control methods are not virtual and so you can't
//override them to do this; you must either hide them or ensure the caller is
//checking for cross-threading.
public void MyWindowMethod()
{
if(InvokeRequired)
this.Invoke(new Action(MyWindowMethod));
else
{
//main logic
}
}
//Input but no return; SetTitle("My Title")
public void MyWindowMethod2(string input)
{
if(InvokeRequired)
this.Invoke(new Action<string>(MyWindowMethod2), input);
else
{
//main logic
}
}
//inputs and outputs; custom methods, advanced graphics
public string MyWindowMethod3(string input)
{
if(InvokeRequired)
return (string)(this.Invoke(new Func<string, string>(MyWindowMethod3), input));
//No else required; the return makes it redundant
//main logic
}
Safe
code runs on the UI thread. All other code that touches the UI must use theInvoke
route. – Iconolatry