Ini adalah sesuatu yang saya temukan beberapa hari yang lalu, saya mendapat konfirmasi bahwa itu tidak hanya terbatas pada mesin saya dari pertanyaan ini .
Cara termudah untuk melakukan repro adalah dengan memulai aplikasi Windows Forms, tambahkan tombol dan tulis kode ini:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
Program gagal setelah pernyataan Exit () dijalankan. Pada Formulir Windows Anda mendapatkan "Kesalahan membuat pegangan jendela".
Mengaktifkan debugging yang tidak terkelola membuatnya agak jelas tentang apa yang terjadi. The COM modal loop mengeksekusi dan memungkinkan pesan WM_PAINT yang akan disampaikan. Itu berakibat fatal pada formulir yang dibuang.
Satu-satunya fakta yang saya kumpulkan sejauh ini adalah:
- Ini tidak hanya terbatas pada menjalankan dengan debugger. Ini juga gagal tanpa satupun. Agak buruk juga, dialog crash WER muncul dua kali .
- Itu tidak ada hubungannya dengan bitness prosesnya. Lapisan wow64 cukup terkenal, tetapi build AnyCPU mengalami error dengan cara yang sama.
- Itu tidak ada hubungannya dengan versi .NET, 4.5 dan 3.5 crash dengan cara yang sama.
- Kode keluar tidak masalah.
- Memanggil Thread.Sleep () sebelum memanggil Exit () tidak memperbaikinya.
- Ini terjadi pada versi 64-bit Windows 8, dan Windows 7 tampaknya tidak terpengaruh dengan cara yang sama.
- Ini seharusnya perilaku yang relatif baru, saya belum pernah melihat ini sebelumnya. Saya tidak melihat pembaruan relevan yang dikirimkan melalui Pembaruan Windows , meskipun riwayat pembaruan tidak lagi akurat di komputer saya.
- Ini adalah perilaku yang sangat melanggar. Anda akan menulis kode seperti ini di event handler untuk AppDomain.UnhandledException, dan crash dengan cara yang sama.
Saya sangat tertarik pada apa yang mungkin dapat Anda lakukan untuk menghindari kecelakaan ini. Terutama skenario AppDomain.UnhandledException membuat saya bingung; Tidak banyak cara untuk menghentikan program .NET. Harap dicatat bahwa memanggil Application.Exit () atau Form.Close () tidak valid dalam penanganan kejadian untuk UnhandledException, jadi mereka bukan solusi.
PEMBARUAN: Mehrdad menunjukkan bahwa utas finalizer bisa menjadi bagian dari masalah. Saya rasa saya melihat ini dan saya juga melihat beberapa bukti untuk batas waktu 2 detik bahwa CLR memberikan rangkaian finalizer untuk menyelesaikan eksekusi.
Finalizer ada di dalam NativeWindow.ForceExitMessageLoop (). Ada fungsi IsWindow () Win32 di sana yang kira-kira sesuai dengan lokasi kode, offset 0x3c saat melihat kode mesin dalam mode 32-bit. Tampaknya IsWindow () mengalami kebuntuan. Saya tidak bisa mendapatkan pelacakan tumpukan yang baik untuk internal Namun, debugger mengira panggilan P / Invoke baru saja kembali. Ini sulit untuk dijelaskan. Jika Anda bisa mendapatkan jejak tumpukan yang lebih baik maka saya ingin melihatnya. Milikku:
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
Tidak ada di atas panggilan ForceExitMessageLoop, debugger tak terkelola diaktifkan.
This happens on the 64-bit version of Windows 8
Hans bilang begitu!Exit(0)
dengan beberapa 64bit Win7, MengubahExitCode
tidak membantu sekarang menggunakanProcess.GetCurrentProcess().Kill()
tanpa masalah itu berhasilJawaban:
Saya menghubungi Microsoft tentang masalah ini dan tampaknya telah terbayar. Setidaknya saya ingin berpikir begitu :). Meskipun saya tidak mendapatkan konfirmasi resolusi kembali dari mereka, grup Windows sulit untuk dihubungi secara langsung dan saya harus menggunakan perantara.
Pembaruan yang dikirimkan melalui Pembaruan Windows memecahkan masalah. Penundaan 2 detik yang terlihat sebelum kecelakaan tidak lagi ada, sangat menunjukkan bahwa kebuntuan IsWindow () telah diselesaikan. Dan program ditutup dengan rapi dan andal. Pembaruan memasang tambalan untuk Windows Defender, wdboot.sys, wdfilter.sys, tcpip.sys, rpcrt4.dll, uxtheme.dll, crypt32.dll dan wintrust.dll
Uxtheme.dll adalah yang aneh-bebek. Ini mengimplementasikan API tema Gaya Visual dan digunakan oleh program uji ini. Saya tidak bisa memastikan, tetapi uang saya ada di sana sebagai sumber masalahnya. Salinan di C: \ WINDOWS \ system32 memiliki nomor versi 6.2.9200.16660, dibuat pada 14 Agustus 2013 di komputer saya.
Kasus ditutup.
sumber
Saya tidak tahu mengapa itu tidak berhasil "lagi" , tapi saya pikir
Environment.Exit
mengeksekusi finalisator yang tertunda.Environment.FailFast
tidak.Mungkin (karena alasan yang aneh) Anda memiliki finalizer aneh yang tertunda yang harus dijalankan setelahnya, yang menyebabkan hal ini terjadi.
sumber
NativeWindow.ForceExitMessageLoop
terjebak dalam kode terkelola atau tidak terkelola? Apakah itu macet, atau sibuk menunggu atau menunggu pesan atau hal lain?Ini tidak menjelaskan mengapa itu terjadi, tetapi saya tidak akan memanggil
Environment.Exit
penangan peristiwa tombol seperti sampel Anda - sebagai gantinya tutup formulir utama seperti yang disarankan dalam jawaban rene .Sedangkan untuk seorang
AppDomain.UnhandledException
pawang, mungkin Anda bisa mengaturEnvironment.ExitCode
daripada meneleponEnvironment.Exit
.Saya tidak yakin apa yang Anda coba capai di sini. Mengapa Anda ingin mengembalikan kode keluar dari aplikasi Windows Forms? Biasanya kode keluar digunakan oleh aplikasi konsol.
Apakah Anda memiliki coba / tangkap dalam metode Utama? Untuk aplikasi Windows Forms, saya selalu mencoba / menangkap sekitar loop pesan serta penangan pengecualian yang tidak tertangani.
sumber
Application.Exit
bukanEnvironment.Exit
.Saya telah menemukan masalah yang sama di aplikasi kami, kami telah menyelesaikannya dengan konstruksi berikut:
Environment.ExitCode=1; Application.Exit();
sumber