2

非常にマルチスレッド化されたWinFormsデスクトップアプリケーションがあります。3つのスレッドがApplication.Runと他の一連のバックグラウンドワーカースレッドで実行されます。すべてのスレッドを適切にシャットダウンするのはちょっと難しいですが、私はついにそれを正しくしたと思いました。

しかし、実際にアプリケーションをデプロイしたとき、ユーザーはアプリケーションが終了しないことを経験し始めました。System.Threading.Mutexがあり、アプリを複数回実行できないようにしているため、タスクマネージャーに移動して、古いアプリを強制終了してから再度実行する必要があります。

すべてのスレッドは、メインスレッドが終了する前にThread.Joinを取得し、生成した各スレッドにログを追加しました。ログによると、開始するすべてのスレッドも終了し、メインスレッドも終了します。さらに奇妙なことに、SysInternals ProcessExplorerを実行すると、アプリケーションが終了するとすべてのスレッドが消えることがわかります。のように、0個のスレッド(マネージドまたはアンマネージド)がありますが、プロセスはまだ実行中です。

これを開発者のコ​​ンピューターやテスト環境で再現することはできません。これまでのところ、Windows XP(Vista、Windows 7、またはWindows Serverではない)でのみ発生することがわかりました。プロセスはどのようにして0スレッドで実行し続けることができますか?

編集:

ここにもう少し詳細があります。イベントループの1つは、COMオブジェクトを使用してデバイスドライバーと通信するWin32相互運用機能DLLをホストすることです。デバイスドライバーは時間に敏感であり、UIスレッドがかなりの時間(データベース呼び出しの終了を待つなど)ブロックするたびに、デバイスドライバーに干渉するため、独自のスレッドに配置しました。

そこで、メインスレッドがThread.Joinをデバイスドライバースレッドで実行するようにコードを変更しました。これにより、実際にアプリケーションがロックアップしました...結合が完了した後、UIスレッドでさらにいくつかの呼び出しがログに記録され、その後すべてが停止します。デバイスの電源がオフの場合、ドライバーは起動せず、問題は解決します。したがって、アプリケーションがシャットダウンされた後でも、ドライバーがアプリケーションを存続させる責任を負わなければならないようです。

4

3 に答える 3

1

スレッドを作成するときは、それらに IsBackground=true を設定します。メインの UI スレッド/アプリが閉じられると、作成されたすべてのスレッドが自動的にシャットダウンされます。

http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx

于 2010-04-23T16:26:37.553 に答える
0

Application.Run 呼び出しの子が終了していない可能性はありますか? また、実際にアプリケーションが終了する原因は何ですか?すべてのスレッドが終了すると自動的に閉じますか(自動的にそれを行うコードを記述したことを意味します)、それともユーザーが模倣したものですか?

「スレッド完了」イベント コードに競合状態があり、表示されているような結果になることがあるという問題がありました。最後の 2 つのスレッドは同時に終了し、イベントを同時に発生させ、各イベントはそれが最後のスレッドではないと判断するため、スレッド数がゼロであってもアプリケーションは実行を継続します。これを解決するために、競合状態を見つけて排除することができましたが、1 秒または 2 秒ごとにチェックしてスレッドの数を取得し、まだ開いているスレッドがない場合はアプリケーションを強制終了するタイマーを使用することもできます。

于 2010-04-23T16:07:00.917 に答える
0

根本的なプログラム上の原因を突き止めることはできませんでしたが、問題の原因となったのは特定のドライバー バージョンであり、新しいドライバーにアップグレードすることで問題が修正されました。

残念ながら、他の誰かがいつか同様の問題に遭遇した場合、これが私ができるすべての答えです...

于 2010-10-22T17:42:59.603 に答える