2011-07-08 7 views
3

メッセージの処理にキューにAutoResetEvent(WaitOne/Set)を使用するアプリケーションがあります。私は、Visual Studio(Shift + F5)からデバッグセッションを終了すると、アプリケーションの元のプロセスがハングアップすることに気付いています(常にそうとは限りません)。私は手動でデバッガをプロセスに再接続し、WaitHandle.WaitOneに1つのスレッドが残っていることを確認します。スレッドは、WaitOne状態のAutoResetEvent信号によってアプリケーション終了後も保持されます。

私の質問は、WaitOne状態のスレッドを終了させる正しい方法は何ですか?

最初の答えはApplication Exitイベントを聞いてそこでSetを実行することでしたが、このイベントがこれらのデバッグセッションの後に確実に呼び出されたかどうか、またはより標準的なプラクティスがあるかどうかはわかりませんでした私は気づいていない。

もう1つの質問として、「生産」モードで実行されているアプリケーションでこれを別に処理しますか?

+0

ええ、あなたの手には厄介な問題があります。デバッグセッションを終了するには、Windowsで利用可能な最大のものであるTerminateProcess()を使用します。 Taskmgr.exeで使用されているのと同じ種類の銃。プロセスが終了しない、カーネルスレッドがビジー状態で、I/O要求を完了していない可能性のある方法は1つだけです。それは、確かにAutoResetEventではありません。意味がありません。 –

+0

@Hans - デバッガを接続するとWaitHandleがコールスタックに表示されますが、信号の待機ハンドルではなく、カーネルI/Oタスクの別の待機ハンドルですか?この仕事の唯一のI/Oはいくつかのロギングであり、それは実際には非常に簡単です(そして、何度も何度も何度も手動でトリガーされます)。 – Matt

+0

私が知っている限り、センス。どんなドキュメンテーションもなければ、私は容易に説明が間違っていると思います。アンマネージデバッグとMicrosoftシンボルサーバーを有効にしてスタックトレースを送信します。 –

答えて

4

があり、あなたはあなたのアプリケーションが

// somewhere with global scope. On a singleton or in program class maybe 
// this is set when you want to terminate your application 
private static ManualResetEvent ExitWaitHandle = new ManualResetEvent(false); 

を死ぬつもりであり、これはどのようにされたときに発動するイベントを設定する必要があります

"some"コードの後に​​は、スレッドを中止するためにチェックポイントを設定する必要があります。これがあなたが探していたものだと願っています。

+1

これは非常に興味深い答えです。私は明日この最初のことを試して、それがどうなるかを教えてくれるでしょう。ありがとう。 – Matt

+0

私は私の前に自分のコードを持っていることをもう一度見ているし、いくつか質問があります。 1)あなたの「グローバル」スコープのExitWaitHandleが公開されるはずですか? 2)シャットダウンプロセス中にExitWaitHandle経由でシグナルの 'ゲート'を開いて、待機ハンドルを解放して自分自身を処分できるという基本的な考え方はありますか? – Matt

+0

@Mattはい、あなたは "ゲート"を開きます!イベントに関しては、公開されるべきではなく、アプリケーション終了イベントを聞く必要があるすべてのクラスからアクセス可能であるべきである。サブスクライバがスレッドであるオブザーバパターンを実装できます。そして少しコードナチのコメント:私はそのようなもののために 'public'の代わりに' internal'キーワードを好む。 – Odys

1

Thread.IsBackgroundプロパティを使用して、スレッドをバックグラウンドスレッドとして設定することです。スレッドに設定されている場合、そのスレッドは終了するプロセスを停止しません。

しかし、スレッドはいつでも中断されて、スレッドが何をしているかによっては未定義の動作につながることがあります。私の謙虚な意見でスレッドを終了させる最善の方法は、スレッドを終了するように知らせることです。終了フラグを設定してWaitHandleを設定して起動すると、スレッドはJoinになります。これを実行するための簡単な方法(ない回避策)

まず

+0

スレッドは実際に.NET 4 Taskオブジェクトを介して処理されています。私はいくつかのマニュアルスレッドを行うことができると思います... – Matt

関連する問題