C#でのThreadAbortExceptionとグレースフルイベントハンドルの終了
-
03-07-2019 - |
質問
スレッドの実行を中止するとき、私はいつも次のようなイベントハンドラーと正常な終了の間を疑っています:
int result = WaitHandle.WaitAny(handles);
if (result = WAIT_FINALIZE)
FinalizeAndExit();
そしてイベントを使用して、終了する必要があるスレッドにシグナルを送ります
または単にThreadAbortExceptionを処理してスレッドを終了します...
try
{
// Main execution
}
catch(ThreadAbortException e)
{
// FinalizeAndExit();
}
finally
{
}
通常はThreadAbortExceptionアプローチを使用する傾向があります。これは処理できますが、catchブロックの最後で再発生し、「危険」によってスレッドが生き続けることも回避するためです。メソッドが、両方のアプローチを見てきました。
あなたの意見は?あるものを他のものよりも使用するのが最善の状況、または常にアプローチxを使用するのが最善の状況はありますか?
解決
一般的に、最初の方法が望ましい。
常にThreadAbortExceptionを適切に処理するコードを記述することは(不可能ではないにしても)困難です。例外は、スレッドが実行していることの途中で発生する可能性があるため、状況によっては処理が難しい場合があります。
たとえば、FileStreamオブジェクトの作成後、参照が変数に割り当てられる前に例外が発生する可能性があります。つまり、破棄する必要があるオブジェクトがありますが、そのオブジェクトへの唯一の参照はどこかのスタックで失われます...
他のヒント
できれば、Thread.Abortの使用を避けるようにします。 Thread.Abortの問題は、実行中のコードの(ほぼ)任意の行で発生する可能性があり、いくつかの「興味深い」ことを引き起こす可能性があることです。動作(読み取り:バグ)。 私は、スレッドが実行を停止して正常に終了するかどうかを確認するために、イベントまたは変数をチェックするコードに終了ポイントを置くことを好みます。
確かに終了イベントが予想される場合、それは例外ではない(用語の厳密な定義による)ので、最初の方法を使用する必要があります。優雅な出口はまた、あなたがコントロールしていることを示します。
例外は便利ですが、場合によっては必要ですが、使い古される可能性があります。