GUI コードに奇妙な動作があります。ユーザーが短時間に大量のイベントを生成すると、実行中のイベント ハンドラー メソッドが別のイベント ハンドラー メソッドによって中断されることがあります。すべてが同じスレッド (GUI スレッド) で実行されるため、すべてが順次実行され、中断が可能であってはなりません。それとも何か誤解しているのでしょうか?
アドバイスありがとう、エニー
GUI コードに奇妙な動作があります。ユーザーが短時間に大量のイベントを生成すると、実行中のイベント ハンドラー メソッドが別のイベント ハンドラー メソッドによって中断されることがあります。すべてが同じスレッド (GUI スレッド) で実行されるため、すべてが順次実行され、中断が可能であってはなりません。それとも何か誤解しているのでしょうか?
アドバイスありがとう、エニー
いいえ、そうはなりません。スレッドが順番に実行されることはご理解のとおりです。
GUI スレッドは中断できますが、別のスレッドを実行するためだけに、別のイベントを処理するために GUI スレッドに再び入ることはありません。スレッドには命令ポインターが 1 つしかないため、コード内の 1 か所にしか存在できず、それ自体で中断することはできません。
GUI スレッドが再入力されたように見える場合は、別の理由があります。
Application.DoEvents
ただし、GUI スレッドは、メソッドを呼び出すことによってそれ自体を「中断」することができます。
シングルスレッドアプリケーションでは、イベントを順番に実行する必要があります。いくつかの例外があります:
イベントが発生し、サブスクライバー リストの最初のイベント ハンドラーが呼び出されます。イベント ハンドラーは、他のイベント ハンドラーを呼び出す独自のイベントを発生させます。この場合、イベントが中断されたように見えますが、そうではありませんでした。元のイベント ハンドラーが完了すると、リスト内の次のイベント ハンドラーが呼び出されます。
イベント ハンドラーがApplication.DoEvents()
メソッドを呼び出します。これにより、現在のイベントが中断され、メッセージ キューで待機しているすべてのメッセージが処理されます (通常、メッセージ キューは独自のイベントを発生させます)。すべてのメッセージの処理が完了すると、イベントに戻ります。Application.DoEvents()
処理されたメッセージの 1 つからイベントを起動した結果として、それを呼び出したイベントへの再帰呼び出しが発生すると、問題が発生する可能性があります。
イベント ハンドラーは、異なるスレッドで実行される場合があります。一部のイベントは UI スレッドでは発生せず、独自のスレッドで発生する場合があります。これにより、イベントが順不同で起動され、スレッド コンテキスト スイッチで互いに中断される可能性があります。消費するイベントが UI スレッドで発生していることを確認し、そうでない場合はControl.Invoke()
UI スレッドで発生させます。おそらく気付かないうちに別のスレッドで発生するイベントの例は、System.Threading.Timer.Elapsed
イベントです。