[解決済み] Environment.Exit()でプログラムが終了しなくなったのはなぜですか?
質問
これは数日前に発見したことなのですが、私のマシンに限ったことではないことを、以下のサイトから確認しました。 この質問 .
最も簡単な再現方法は、Windows Formsアプリケーションを起動し、ボタンを追加して、このコードを書くことです。
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
プログラムが失敗する の後 Exit() ステートメントが実行された後、プログラムは失敗します。Windows Formsでは、"Error creating window handle"と表示されます。
アンマネージドデバッグを有効にすると、何が起こっているのかがある程度明確になります。そのため COM モーダルループが実行され、WM_PAINT メッセージが配信されるようになりました。これは、破棄されたフォームでは致命的です。
私がこれまでに集めた唯一の事実は
- デバッガーを使って実行する場合に限ったことではありません。 これはまた、デバッガなしでも失敗します。 むしろ同様に悪いことに、WER クラッシュ ダイアログが表示されます。 2 回 .
- プロセスのビット数とは関係ありません。wow64 レイヤーはかなり悪名高いですが、AnyCPU ビルドも同じようにクラッシュします。
- .NET のバージョンとは関係なく、4.5 と 3.5 は同じようにクラッシュします。
- 終了コードは重要ではありません。
- Exit()を呼び出す前にThread.Sleep()を呼び出しても直らない。
- これは Windows 8 の 64 ビット版で発生し、Windows 7 は同じように影響されないようです。
- これは比較的新しい動作のはずで、以前には見たことがありません。 関連する更新プログラムが Windows アップデート を通じて配信された関連する更新プログラムはありません。ただし、私のマシンでは更新履歴が正確ではなくなっています。
- これは、著しく破損した動作です。AppDomain.UnhandledException のイベント ハンドラでこのようなコードを書くと、同じようにクラッシュします。
私は特に、このクラッシュを回避するために何ができる可能性があるかに興味があります。 特に AppDomain.UnhandledException のシナリオは私を困惑させます。.NET プログラムを終了させる方法はあまり多くありません。 Application.Exit() または Form.Close() を呼び出すことは、UnhandledException のイベント ハンドラでは有効ではないので、回避策にはならないことに注意してください。
UPDATE: Mehrdad は、ファイナライザースレッドが問題の一部である可能性を指摘しました。 私はこれを確認し、また、CLR がファイナライザー スレッドに実行を終了させるために与える 2 秒間のタイムアウトに関するいくつかの証拠を確認していると思います。
ファイナライザーは NativeWindow.ForceExitMessageLoop() の内部にあります。 そこには IsWindow() Win32 関数があり、32 ビット モードでマシン コードを見たときに、コードの場所、オフセット 0x3c にほぼ対応しています。 IsWindow()はデッドロックしているようです。 しかし、内部のスタック トレースを取得することはできません。 P/Invoke の呼び出しがちょうど返されたと考えています。 これは説明するのが難しいです。 もし、もっと良いスタックトレースがあれば、ぜひ見てみたいものです。 私のです。
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.ForceExitMessageLoop() + 0x3c bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Finalize() + 0x16 bytes
[Native to Managed Transition]
kernel32.dll!@BaseThreadInitThunk@12() + 0xe bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
ForceExitMessageLoop 呼び出しの上には何もなく、アンマネージドデバッガが有効になっています。
どのように解決するのですか?
私はこの問題について Microsoft に連絡し、それが功を奏したようです。 少なくとも、そうであったと思いたいのです。) 解決の確認は得られなかったのですが、Windows グループは直接コンタクトするのが難しく、仲介者を利用する必要がありました。
Windows Update で配信される更新プログラムによって、問題は解決しました。 クラッシュする前の顕著な 2 秒の遅延はもはや存在せず、IsWindow() のデッドロックが解決されたことを強く示唆します。 また、プログラムはクリーンかつ確実にシャットダウンされます。 この更新は、Windows Defender、wdboot.sys、wdfilter.sys、tcpip.sys、rpcrt4.dll、uxtheme.dll、crypt32.dll および wintrust.dll に対するパッチをインストールします。
Uxtheme.dll は奇抜なものです。これは Visual Styles テーマ API を実装しており、このテスト プログラムで使用されています。確証はありませんが、問題の原因はこの 1 つにあると私は考えています。 C:\WINDOWSsystem32 にあるコピーはバージョン番号 6.2.9200.16660 で、私のマシンでは 2013 年 8 月 14 日に作成されました。
一件落着。
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み] 配置されたアセンブリのマニフェスト定義がアセンブリ参照と一致しない
-
[解決済み] Could not find a part of the path ... binroslyncsc.exe
-
[解決済み] 名前 'ConfigurationManager' は、現在のコンテキストに存在しません。
-
[解決済み] C#の[Flags]Enum属性の意味とは?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] フォルダが存在しない場合、作成する
-
[解決済み] lockステートメントは、ボンネットの中で何をするのでしょうか?
-
[解決済み] Visual Studioの「Any CPU」ターゲットはどういう意味ですか?
-
[解決済み】非同期処理の待ち時間、Wait()でプログラムがフリーズする原因はここにある
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】2つ(またはそれ以上)のリストを1つに統合する(C# .NETで
-
[解決済み】 C# 条件演算子エラー 代入、call、increment、decrement、await、new object 式のみ文として使用可能です。
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない