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.