私は他の人のコードを調べていますが、マルチスレッドに関係する経験はあまりありません。このコード行に出くわしました:
BeginInvoke((MethodInvoker)delegate() { btnCalibrate.PerformClick(); });
これだけでうまくいくのに、なぜこれを行うのだろうと思っていました:btnCalibrate.PerformClick();
回答ありがとうございます。
私は他の人のコードを調べていますが、マルチスレッドに関係する経験はあまりありません。このコード行に出くわしました:
BeginInvoke((MethodInvoker)delegate() { btnCalibrate.PerformClick(); });
これだけでうまくいくのに、なぜこれを行うのだろうと思っていました:btnCalibrate.PerformClick();
回答ありがとうございます。
このコードがGUIでボタンを作成したスレッドとは異なるスレッドで実行された場合、例外がスローされるためです。GUIはスレッドセーフではないため、バックグラウンドスレッドはGUIのメソッドを直接呼び出すことはできません。
もちろん、これがBeginInvoke!を使用する合理的な理由です。しかし、正当な理由もなく投入されたばかりの呪文や魔法の呪文を含むコードを見つけることは珍しいことではありません。使用しているコードがシングルスレッドの場合、それは不要です。
特に、Windowsフォーム自体は断固としてシングルスレッドです。すべてのウィンドウとコントロールに対するすべての操作は同じスレッドで発生し、それらのすべてのイベントは同じスレッドで発生します。1つのGUIスレッドの使用は、スレッド上で継続的に実行され、キューからメッセージを読み取るメッセージループによって分割されます。BeginInvokeの目的は、最終的にはそのキューにメッセージを投稿し、「時間があれば、このコードのチャンクを実行してください」と効果的に伝えることです。
@Earwicker を少し拡張するには、Control.BeginInvoke は、あるスレッドから Control インスタンスを所有するスレッドに呼び出しを転送する方法です。バックグラウンドでは、所有スレッドPostMessageのメソッドへの呼び出しをマーシャリングするために呼び出される Win32 関数を介して Win32 メッセージを使用しています。PerformClickこれは、Win32 Windows と、WinForms Controls の拡張により、それを作成したスレッド (通常は GUI を実行する単一のスレッド) からのみ安全にアクセスできるために必要です。
BeginInvoke使用されている理由とはInvoke、前者は使用PostMessageしてすぐに返されるのに対し、後者は隠れて使用し、待機して GUI スレッドからの応答を待つSendMessage必要があるためです。PostMessageこれにより、呼び出しを行うスレッドが遅延したり、アプリケーションがロックアップしたりする可能性があるため、BeginInvokeここではより適切な選択です。