まず第一に、Thread.Abort()は悪です-わかりました!それでは、私の状況を説明しましょう...
状況:
現在の実行ステータスのみをユーザーに表示するダッシュボードがあります。SQL Server DBに対してさまざまな選択クエリを実行し、最終的にダッシュボードにユーザーに表示されるいくつかの計算を実行します。ユーザーは同時に複数のダッシュボードを開くことができます。ダッシュボードを数秒ごとに更新するタイマースレッドがあります。そのタイマースレッドは別のスレッドを生成し(実際にはキューはスレッドプールで機能します)、長時間実行される計算/クエリを実行します。
問題:
ユーザーがXをクリックしてダッシュボードウィンドウを閉じるときは、すぐにシャットダウンする必要があります(たとえば、1秒以内に2秒は長すぎると思います)。だから私はこのコードを使用します:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_timerThread.Abort();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// we're on the timer thread now
try
{
RefreshUi();
}
catch (ThreadAbortException)
{
System.Threading.Thread.ResetAbort();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
問題は、ThreadAbortExceptionがキャッチされる場合と、キャッチされない場合があります。クエリを実行している最中は、ほとんどキャッチされていません。
[更新] innerexceptionをチェックすると、ThreadAbortExceptionをキャッチできることを最近発見しました。
質問:
- この場合、Thread.Abort()を使用しても大丈夫ですか?その場合、フォームを閉じたときにユーザーに表示されないように、常にThreadAbortExceptionをキャッチするにはどうすればよいですか?(私が読んだことから、これは可能ではないと思います)
- Thread.Abort()を使用しても問題がない場合(これはほとんどの人が答えると思います)、「グローバルブールフラグ」を使用してスレッドにシャットダウンするタイミングを指示することに関するその他の懸念事項があります。
- スレッドが1秒の制限時間内に停止しないのではないかと心配しています。(たとえば、実行に1〜2秒かかるクエリがある場合があります)
- if(shouldShutdown)ステートメントでコードを乱雑にする必要があります。
- すべてのクラスが使用できるように、shouldShutdownフラグを静的にする必要がありますか?ユーザーが複数のダッシュボードを同時に開くことができる場合、これは問題になりますか?(静的変数がすべてのダッシュボードで共有されることを懸念しています。これは絶対に必要ありません。)
- ワーカースレッドがシャットダウンする必要があることを確認したら、例外をスローする必要がありますか、それとも単に戻る必要がありますか?それらがちょうど戻った場合、一部の関数がfalseを返しても問題ないため、if(shouldShutdown)チェックをさらに追加する必要があります。例外をスローしても問題がない場合、どの例外をお勧めしますか?カスタムのもの?
ありがとう