2012-06-13 13 views
11

私はIsBackgroundプロパティをtrueに設定したC#でスレッドを使用しています。スレッドは、アプリケーションが終了するまでループ内でコードを実行しています。アプリケーションが閉じられると、スレッドも実行を停止します(IsBackground = trueに設定されているため)。アプリケーションが終了したときに、バックグラウンドスレッドがアプリケーションによって強制終了されたことを検出できますか?

どのようにアプリケーションがスレッドを強制終了しますか?私はThreadAbortExceptionを取得していないので、中断を呼び出すことでそれをしないようです。背後で起こるのだろうか?私はループの私の最終的なブロックでいくつかのロールバックをしたいと思います。

スレッドで自分自身を中止することはできますが、アプリケーションがバックグラウンドスレッドをどのように閉じるのか、スレッド内から反応できるかどうかを知りたいと思っています。私はApplication.ApplicationExitイベントを購読することができますが、サービスとwinformの両方でこのコードを実行しています。ループ内で例外をキャッチしてfinallyステートメントでロールバックできるようにしたいと思います。

+0

フォアグラウンドスレッドにして、スレッドを手動で閉じる「グローバル」アプリケーションシャットダウンシナリオを作成できます。 – CodingBarfield

+0

[AppDomain.ProcessExit](http://msdn.microsoft.com/en-us/library/system.appdomain.processexit.aspx)イベントを見ましたか? – Botz3000

+0

こういうふうに、このようなカスタムソリューションを作る以外に、私はそれが場面の裏で起こっていると言っています。 –

答えて

5

それは私がそれがないThreadAbortExceptionの

を得ることはありませんので、それは中止呼び出すことによって、それをしないと思われ、CLRは、スレッドを中止するには、2つの方法があります。 Thread.Abort()によって呼び出される「通常の」方法では、スレッドはThreadAbortExceptionを見ることができます。しかし、失礼な中止もあり、同じように動作します。しかし、TAEを除いて最終的にブロックは実行されません。あなたはそれを観察することはできません。

+0

Aha ..それを分けてくれてありがとう。私はこの文書を見つけることができませんでした –

+0

MSDNで間違っていますか? http://msdn.microsoft.com/en-us/library/system.threading.threadabortexceptionaspx 管理された実行可能ファイル内のすべてのフォアグラウンドスレッドが終了した後、共通言語ランタイム(CLR)がバックグラウンドスレッドを停止すると、Thread.Abortは使用されません。したがって、ThreadAbortExceptionを使用して、バックグラウンドスレッドがいつCLRによって終了しているかを検出することはできません。 – Eldar

+0

MSDNの記事とこの回答との間に矛盾はありません。あなたはAppDomain.UnloadやEnvironment.Exitを必要とします。一般に、スレッドを中止する方法として最初に考えている方法ではありません:) –

1

開始threadは、オペレーティングシステムがプロセッサをthreadに割り当てると、実行状態になります(実行を開始します)。開始スレッドがプロセッサを初めて受信して実行スレッドになると、そのスレッドはThreadStart delegateを実行します。このスレッドは、そのライフサイクル中にスレッドが実行するアクションを指定します。プログラムが新しいThreadを作成するとき、プログラムはスレッドのThreadStart delegateをThreadコンストラクタの引数として指定します。

実行スレッドは、ThreadStart delegateが終了するとStopped (or Dead)状態になります。あなたの場合、メインスレッドは終了します。したがって、ThreadStart delegateオブジェクトはメモリに残りません。スレッドオブジェクトへの参照がない場合、ガベージコレクタはメモリからスレッドオブジェクトを削除できます。

+0

これの良い説明に感謝します。 私は、Botz3000が提案したようにAppDomain.ProcessExitイベントを使用してしまいました。このイベントが発生すると、thread.Abort()を呼び出すことができます。うまくいくようです。 –

+0

この回答は間違っています。放棄されたバックグラウンドスレッドは、収集したGCによって中止されません。管理対象スレッドオブジェクトに対する強い参照に関係なく、ランタイムによって強制的に中断されます。説明についてはハンスの答えを見てください。 – Josh

+0

@JoshEinstein:正しいかもしれませんが、HansはCLRがスレッドを異常終了させる方法を説明しませんでした。 – Talha

関連する問題