C#では、Thread.Startメソッドを使用してスレッドを開始できることは誰もが知っています。実行中のスレッドを停止する場合は、Thread.Abortメソッドを使用して実行中のスレッドを強制的に停止できますが、必ず注意してください。スレッドを呼び出すにはスレッドは.Abortメソッドの直後に停止しますか?答えはいいえだ!
Abortメソッドがどのように機能するかを説明しましょう。共通言語ランタイムはすべての管理対象スレッドを管理するため、各スレッドで例外をスローすることもできます。Abortメソッドは、ターゲットスレッドでThreadAbortExceptionをスローし、ターゲットスレッドを終了させる可能性があります。ただし、Abortメソッドが呼び出された後、ターゲットスレッドがすぐに終了しない場合があります。ターゲットスレッドがアンマネージコードを呼び出して戻ってこない限り、スレッドはすぐには終了しません。また、ターゲットスレッドがアンマネージコードを呼び出して無限ループに陥った場合、ターゲットスレッドはまったく終了しません。ただし、この状況は特殊なケースにすぎません。多くの場合、ターゲットスレッドはマネージコードを呼び出しています。Abortが呼び出されると、スレッドはすぐに終了します。
実際、スレッドが実行されているときは、Thread.ThreadStateプロパティを介してその状態を読み取ることができ、実行中のスレッドの状態はThreadState.Runningです。次に、実行中のスレッドを強制的に停止する場合は、Thread.Abortメソッドを呼び出しますが、Thread.Abortメソッドが行うことは、スレッドでThreadAbortException例外をスローし、スレッドの状態をThreadState.AbortRequested、MSDNに設定することです。 AbortRequested状態の説明は次のとおりです。Thread.Abortメソッドがスレッドで呼び出されましたが、スレッドは、それを終了しようとする保留中のSystem.Threading.ThreadAbortExceptionをまだ受信していません。これは、スレッドがThreadState.AbortRequestedにあることを意味します。状態、それが終わりに近づいていることを示しますが、それでも本当の終わりはありません。ただし、Thread.Abortメソッドはスレッドの状態をThreadState.AbortRequestedに設定してすぐに戻り、スレッドが実際に終了した後の状態はThreadState.Abortedである必要があるため、Thread.Abortメソッドを呼び出した後にループを確認することを忘れないでください。 Thread.ThreadStateプロパティを使用するか、Thread.Joinメソッドを呼び出して、終了したスレッドが実際に停止したことを確認します。Thread.ThreadStateプロパティが中止された場合、またはThread.Joinメソッドが戻った場合にのみ、スレッドが実際に終了したことを意味します。
以下にサンプルコードを記述して、Thread.Abortメソッドを呼び出した後にスレッドが停止した後もコードが実行され続けるようにする方法を説明します。
var thread = new Thread( new ThreadStart( ()=> { while(true) { //スレッドは無限にループし、それ自体では終了しません Thread.Sleep(100); } })); thread.IsBackground = true; thread.Start(); //スレッドを開始 thread.Abort(); // Thread.Abortメソッドを呼び出して、スレッドスレッドを強制的に終了しようとします //スレッドスレッドは、上記のThread.Abortメソッドを呼び出した直後に終了しない場合があります。これが、スレッドが本当に停止したかどうかを確認するためのループです。実際、ここでThread.Joinメソッドを使用して、スレッドが終了するのを待つこともできます。Thread.Joinメソッドは、ここで記述したループ効果と同じことを行い、スレッドスレッドが終了するまでメインスレッドをブロックします (thread .ThreadState!= ThreadState.Aborted) { // Abortメソッドが呼び出されたときに、スレッドスレッドの状態がAbortedでない場合、メインスレッドは、スレッドスレッドの状態がAbortedになるまでここでループし続けます。 Thread.Sleep(100); } //上記のループから抜け出すと、開始したスレッドスレッドが完全に終了したことを意味します