Bu sadece birkaç gün önce keşfettiğim bir şey, bu sorudan sadece makinemle sınırlı olmadığını doğruladım .
Yeniden oluşturmanın en kolay yolu bir Windows Forms uygulaması başlatmak, bir düğme eklemek ve şu kodu yazmaktır:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
Exit () ifadesi çalıştırıldıktan sonra program başarısız olur . Windows Forms'da "Pencere tutamacı oluşturulurken hata oluştu" iletisi görüntülenir.
Yönetilmeyen hata ayıklamayı etkinleştirmek, neler olup bittiğini biraz netleştirir. COM kalıcı döngü yürütme ve WM_PAINT mesajı teslim edilecek olanak tanır. Bertaraf edilmiş bir formda ölümcüldür.
Şimdiye kadar topladığım tek gerçekler:
- Sadece hata ayıklayıcı ile çalışmakla sınırlı değildir. Bu da olmadan başarısız olur. Aksine kötü yanı, WER iletişim gösterileri yukarı çökmesine iki kez .
- Sürecin bitliği ile ilgisi yoktur. Wow64 katmanı oldukça kötü şöhretlidir, ancak AnyCPU derlemesi aynı şekilde çöker.
- .NET sürümü ile ilgisi yoktur, 4.5 ve 3.5 aynı şekilde çöküyor.
- Çıkış kodu önemli değil.
- Exit () öğesini çağırmadan önce Thread.Sleep () öğesini çağırmak sorunu çözmez.
- Bu, Windows 8'in 64 bit sürümünde gerçekleşir ve Windows 7 aynı şekilde etkilenmez.
- Bu nispeten yeni bir davranış olmalı, bunu daha önce görmedim. Güncelleme geçmişinin makinemde artık doğru olmamasına rağmen, Windows Update aracılığıyla hiçbir alakalı güncelleme görmüyorum .
- Bu son derece kırıcı bir davranıştır. AppDomain.UnhandledException için bir olay işleyicisine böyle bir kod yazarsınız ve aynı şekilde kilitlenir.
Özellikle bu çökmeyi önlemek için neler yapabileceğinizle ilgileniyorum. Özellikle AppDomain.UnhandledException senaryosu beni yoruyor; .NET programını sonlandırmanın pek bir yolu yoktur. UnutulmazException için bir olay işleyicisinde Application.Exit () veya Form.Close () öğesinin çağrılmasının geçerli olmadığına, bu nedenle geçici çözüm olmadığına dikkat edin.
GÜNCELLEME: Mehrdad, sonlandırıcı ipliğin sorunun bir parçası olabileceğine dikkat çekti. Ben bunu görüyorum ve ayrıca CLR sonlandırıcı iplik yürütme bitirmek için verir 2 saniye zaman aşımı için bazı kanıt görüyorum düşünüyorum.
Sonlandırıcı NativeWindow.ForceExitMessageLoop () içinde. 32 bit modunda makine koduna bakarken yaklaşık olarak kod konumuna karşılık gelen bir IsWindow () Win32 işlevi var, 0x3c ofset. Görünüşe göre IsWindow () kilitlenmiyor. Ancak iç için iyi bir yığın izleme alamıyorum, hata ayıklayıcı P / Invoke çağrısı sadece geri döndü düşünüyor. Bunu açıklamak zor. Eğer daha iyi bir yığın izleme alabilirsiniz o zaman görmek isterim. Benim:
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 çağrısının üstünde hiçbir şey yok, yönetilmeyen hata ayıklayıcı etkin değil.
This happens on the 64-bit version of Windows 8
Hans bunu söyledi!
Exit(0)
64bit Win7 ile biraz önce bu tür davranışlarla karşılaştım , Değişen ExitCode
artık Process.GetCurrentProcess().Kill()
işe yaradığı herhangi bir sorun olmadan kullanmanıza yardımcı olmuyor