スレッドを終了するだけでなく、実際に中止を行いたいと仮定すると、スレッド参照をコレクションに保存してから全員に対して abort() を呼び出すことができない理由はありますか?
以下のコメントは正しいです。キャンセル トークンをリッスンしてスレッドを終了した方がよいでしょう。ただし、特定のスレッドを制御できない場合があります。たとえば、サード パーティのライブラリが原因で、スレッド コード内で何かが応答しないとします。これは、中止を呼び出すのに適した時期です。適切にクリーンアップされるものは何もないこと、finally ブロックが実行されないこと、破棄する必要のあるハンドルが破棄されないことなどに注意してください。abort を呼び出すのはかなり汚い仕事です。
スレッドで実行されているコードにアクセスできる場合は、キャンセル トークンをリッスンする必要があります。または、ベイル アウトの時期を示す共有 (揮発性) ブール値だけをリッスンする必要があります。スレッドに long がある場合は、Thread.Sleep()
それをミューテックスに置き換えて、スレッドを起動し、正常に終了するように指示することができます。
IsBackground
スレッドのプロパティを参照します。MSDNによると
バックグラウンド スレッドは、バックグラウンド スレッドがプロセスの終了を妨げないことを除いて、フォアグラウンド スレッドと同じです。
したがって、アプリの実行中にスレッドを終了する必要がある場合、このプロパティを設定しても何も起こりません。
ポイントを説明する例を次に示します
public class DisposeTest : IDisposable
{
public void Run()
{
while (true)
{
Thread.Sleep(TimeSpan.FromDays(1));
}
Dispose();
}
public void Dispose()
{
Console.WriteLine("disposing");
}
}
public class TestDriver
{
static void Main(string[] args)
{
var diposeTest = new DisposeTest();
var thread = new Thread(diposeTest.Run)
{
IsBackground = true
};
thread.Start();
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
このアプリでは、アプリケーションがハングせず、エラーなしで終了したにもかかわらず、dispose がヒットすることはありません。ソケットを開いたままにしたり、ファイルを閉じたり、SQL クエリを未完成にしたり、あらゆる種類のものを放置できるため、これは悪い考えです。
スレッドを終了する方法はたくさんありますが、気を付けないと、abort で終了すると副作用が発生する可能性があるため、終了方法に注意してください。