Saya memiliki panggilan rekursif ke metode yang melempar pengecualian stack overflow. Panggilan pertama dikelilingi oleh blok coba tangkap tetapi pengecualian tidak tertangkap.
Apakah pengecualian stack overflow berperilaku dengan cara khusus? Bisakah saya menangkap / menangani pengecualian dengan benar?
Tidak yakin apakah relevan, tetapi informasi tambahan:
pengecualian tidak ditampilkan di utas utama
objek tempat kode melemparkan pengecualian dimuat secara manual oleh Assembly.LoadFrom (...). CreateInstance (...)
c#
try-catch
stack-overflow
Toto
sumber
sumber
Assert.Fail
gantinya. Sangat serius - bagaimana kita melakukannya?Jawaban:
Dimulai dengan 2.0, Pengecualian StackOverflow hanya dapat ditangkap dalam keadaan berikut.
* "lingkungan yang dihosting" seperti dalam "kode saya menghosting CLR dan saya mengonfigurasi opsi CLR" dan bukan "kode saya berjalan di hosting bersama"
sumber
Starting with 2.0 ...
, Saya penasaran, apa yang mencegah mereka menangkap SO dan bagaimana mungkin1.1
(Anda sebutkan dalam komentar Anda)?Cara yang benar adalah dengan memperbaiki overflow, tapi ....
Anda dapat memberi diri Anda tumpukan yang lebih besar: -
Anda dapat menggunakan properti System.Diagnostics.StackTrace FrameCount untuk menghitung bingkai yang telah Anda gunakan dan menampilkan pengecualian Anda sendiri saat batas bingkai tercapai.
Atau, Anda dapat menghitung ukuran tumpukan yang tersisa dan memberikan pengecualian Anda sendiri saat berada di bawah ambang batas: -
Tangkap kejunya. ;)
sumber
Cheese
jauh dari spesifik. Saya akan pergi untukthrow new CheeseException("Gouda");
Dari halaman MSDN di StackOverflowException :
sumber
Seperti yang telah dikatakan beberapa pengguna, Anda tidak dapat menangkap pengecualian. Namun, jika Anda kesulitan mencari tahu di mana itu terjadi, Anda mungkin ingin mengonfigurasi studio visual agar berhenti ketika dilempar.
Untuk melakukan itu, Anda perlu membuka Pengaturan Pengecualian dari menu 'Debug'. Dalam versi Visual Studio yang lebih lama, ini ada di 'Debug' - 'Pengecualian'; dalam versi yang lebih baru, ada di 'Debug' - 'Windows' - 'Exception Settings'.
Setelah Anda membuka pengaturan, perluas 'Common Language Runtime Exception', perluas 'System', gulir ke bawah dan centang 'System.StackOverflowException'. Kemudian Anda dapat melihat tumpukan panggilan dan mencari pola panggilan yang berulang. Itu akan memberi Anda gambaran tentang ke mana harus mencari untuk memperbaiki kode yang menyebabkan tumpukan melimpah.
sumber
Seperti yang disebutkan di atas beberapa kali, tidak mungkin menangkap StackOverflowException yang dimunculkan oleh Sistem karena status proses yang rusak. Tapi ada cara untuk melihat pengecualian sebagai acara:
Namun aplikasi Anda akan berhenti setelah keluar dari fungsi-acara (solusi yang SANGAT kotor, adalah memulai ulang aplikasi dalam acara ini haha, belum melakukannya dan tidak akan pernah melakukannya). Tapi itu cukup bagus untuk penebangan!
sumber
Ya dari CLR 2.0 stack overflow dianggap sebagai situasi yang tidak dapat dipulihkan. Jadi runtime masih menghentikan proses.
Untuk detailnya silakan lihat dokumentasi http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx
sumber
StackOverflowException
menghentikan proses secara default.Tidak boleh. CLR tidak akan membiarkan Anda. Stack overflow adalah kesalahan fatal dan tidak dapat dipulihkan.
sumber
Anda tidak bisa karena sebagian besar postingan menjelaskan, izinkan saya menambahkan area lain:
Di banyak situs web Anda akan menemukan orang-orang mengatakan bahwa cara untuk menghindarinya adalah menggunakan AppDomain yang berbeda jadi jika ini terjadi domain akan dibongkar. Itu benar-benar salah (kecuali Anda meng-host CLR Anda) karena perilaku default CLR akan memunculkan peristiwa KillProcess, menurunkan AppDomain default Anda.
sumber
Itu tidak mungkin, dan untuk alasan yang bagus (untuk satu, pikirkan tentang semua tangkapan (Pengecualian) {} di sekitar).
Jika Anda ingin melanjutkan eksekusi setelah stack overflow, jalankan kode berbahaya di AppDomain yang berbeda. Kebijakan CLR dapat disetel untuk menghentikan AppDomain saat ini saat melimpah tanpa memengaruhi domain asli.
sumber