中止された状況と完了した状況の両方で、ThreadState
になりますStopped
。
それらを区別する方法は?
元のアサーションが正しくありません。検討:
public static void TestThreadAbort()
{
var t = new Thread(() => Thread.Sleep(50000));
t.Start();
t.Abort();
Thread.Sleep(50);
// Prints "Aborted"
Console.WriteLine(t.ThreadState);
}
ThreadState
列挙型がどのように宣言されているかに注意してください。
[FlagsAttribute]
public enum ThreadState { ... }
...[Flag]
これは、スレッドが複数の状態になる可能性があることを意味します。
MSDN、ThreadState列挙(私が強調を追加):
ThreadStateは、スレッドのすべての可能な実行状態のセットを定義します。スレッドが作成されると、終了するまで少なくとも1つの状態になります。共通言語ランタイム内で作成されたスレッドは、最初は未開始状態ですが、ランタイムに入る外部スレッドはすでに実行状態になっています。開始されていないスレッドは、開始を呼び出すことによって実行状態に移行します。ThreadState値のすべての組み合わせが有効であるとは限りません。たとえば、スレッドをAborted状態とUnstarted状態の両方にすることはできません。
...そして次のように続けます:
スレッドは、一度に複数の状態になる可能性があります。たとえば、あるスレッドがWaitの呼び出しでブロックされ、別のスレッドがブロックされたスレッドでAbortを呼び出す場合、ブロックされたスレッドは同時にWaitSleepJoin状態とAbortRequested状態の両方になります。この場合、スレッドがWaitの呼び出しから戻るか、中断されるとすぐに、スレッドはThreadAbortExceptionを受け取り、中止を開始します。
スレッドのThread.ThreadStateプロパティは、スレッドの現在の状態を提供します。アプリケーションは、ビットマスクを使用して、スレッドが実行されているかどうかを判断する必要があります。Runningの値はゼロ(0)であるため、次のようなC#コードを使用してスレッドが実行されているかどうかをテストします。
(myThread.ThreadState & (ThreadState.Stopped | ThreadState.Unstarted)) == 0
私が考えることができる唯一の方法は、「完了」フラグをスレッドの最後のアクションとして設定することです。そのフラグが設定されていない場合は、中止されたと見なすことができます。@Chris Shain が以下で指摘しているように、どこに置くかに注意する必要がありますThreadAbortException
。finally
スレッドがアボートした場合でも設定されます。
スレッドが中止されたとき。スレッドで ThreadAbortException が発生します。これは、差別化に役立ちます。