非常にマルチスレッド化された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スレッドでさらにいくつかの呼び出しがログに記録され、その後すべてが停止します。デバイスの電源がオフの場合、ドライバーは起動せず、問題は解決します。したがって、アプリケーションがシャットダウンされた後でも、ドライバーがアプリケーションを存続させる責任を負わなければならないようです。