アプリケーションがマルチスレッド化されるように設計されている場合、クロススレッド化が発生する可能性があるため、InvokeRequired を使用してチェックする必要があり、UI スレッドで re-Invoke() 自体を呼び出しているメソッドを持つか、例外をスローする必要があります。コードが不適切に使用されていることを示します。特定の状況では InvokeRequired が false になることに注意してください (主に、ウィンドウにハンドルがないか、破棄されている/破棄されている場合)。このような状況を回避する最善の方法は、ウィンドウの初期化プロセスで Load() イベント ハンドラーより前にスレッドを開始しないことと、ウィンドウによって作成されたバックグラウンド スレッドをキャンセルし、それらが閉じるのを待つことによって Closing() イベントを処理することです。
アプリケーションがマルチスレッド化されていない (BackgroundWorkers、TPL 操作、BeginInvoke()ing デリゲートまたは Start()ing スレッドを設定していない) 場合は、必要ありません。ただし、InvokeRequired の呼び出しは非常に安価です (その背後にあるロジックは、基本的に、WinAPI 関数 GetThreadId と GetWindowThreadProcessId が同じ値を返すことを確認することです)。そのため、プログラムが再構築されてマルチスレッド化されることが予想される場合、呼び出されるメソッドの次のパターンは単純です。実装するのに十分です:
//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
}