Jika blok akhirnya melempar pengecualian, apa yang sebenarnya terjadi?
Secara khusus, apa yang terjadi jika pengecualian dilemparkan di tengah jalan melalui blok akhirnya. Apakah sisa pernyataan (setelah) di blok ini dipanggil?
Saya menyadari bahwa pengecualian akan menyebar ke atas.
c#
exception
exception-handling
try-catch-finally
Jack Kada
sumber
sumber
Jawaban:
Pengecualian itu menyebar keluar dan naik, dan akan (dapat) ditangani pada tingkat yang lebih tinggi.
Blok Anda akhirnya tidak akan selesai melampaui titik di mana pengecualian dilemparkan.
Jika blok akhirnya dieksekusi selama penanganan pengecualian sebelumnya maka pengecualian pertama hilang.
sumber
ThreadAbortException
, maka seluruh blok akhirnya akan selesai terlebih dahulu, karena merupakan bagian kritis.Untuk pertanyaan seperti ini, saya biasanya membuka proyek aplikasi konsol kosong di Visual Studio dan menulis program sampel kecil:
Ketika Anda menjalankan program ini, Anda akan melihat urutan yang tepat di mana
catch
danfinally
blok dieksekusi. Harap dicatat bahwa kode di blok akhirnya setelah pengecualian dilemparkan tidak akan dieksekusi (pada kenyataannya, dalam program sampel ini Visual Studio bahkan akan memperingatkan Anda bahwa ia telah mendeteksi kode yang tidak terjangkau):Keterangan tambahan
Seperti yang ditunjukkan Michael Damatov, pengecualian dari
try
blok akan "dimakan" jika Anda tidak menanganinya dicatch
blok (bagian dalam) . Bahkan, dalam contoh di atas pengecualian yang dilemparkan kembali tidak muncul di blok tangkapan luar. Untuk membuatnya terlihat lebih jelas pada sampel yang sedikit dimodifikasi berikut ini:Seperti yang Anda lihat dari output, pengecualian dalam adalah "hilang" (yaitu diabaikan):
sumber
finally
blok akan (hampir) selalu dieksekusi, ini berlaku juga dalam hal ini untuk blok akhirnya dalam (coba saja program sampel sendiri (Blok akhirnya tidak akan dieksekusi dalam kasus yang tidak dapat dipulihkan) pengecualian, misalnyaEngineExecutionException
, tetapi dalam kasus seperti itu program Anda akan segera dihentikan)Jika ada pengecualian tertunda (ketika
try
blok memilikifinally
tetapi tidakcatch
), pengecualian baru menggantikan yang itu.Jika tidak ada pengecualian yang tertunda, ia berfungsi seperti melempar pengecualian di luar
finally
blok.sumber
catch
blok yang (ulang) melempar pengecualian.Pengecualian disebarkan.
sumber
Cuplikan cepat (dan agak jelas) untuk menyimpan "pengecualian asli" (dilemparkan ke dalam
try
blok) dan mengorbankan "akhirnya pengecualian" (dilemparkan ke dalamfinally
blok), jika yang asli lebih penting bagi Anda:Ketika kode di atas dijalankan, "Pengecualian Asli" menyebarkan tumpukan panggilan, dan "Pengecualian Akhirnya" hilang.
sumber
Saya harus melakukan ini untuk menangkap kesalahan saat mencoba menutup aliran yang tidak pernah dibuka karena pengecualian.
jika webRequest dibuat tetapi terjadi kesalahan koneksi selama
kemudian yang terakhir akan menangkap pengecualian yang mencoba menutup koneksi yang dianggapnya terbuka karena webRequest telah dibuat.
Jika akhirnya tidak memiliki try-catch di dalam, kode ini akan menyebabkan pengecualian tidak tertangani saat membersihkan webRequest
dari sana kode akan keluar tanpa benar menangani kesalahan yang terjadi dan karena itu menyebabkan masalah untuk metode panggilan.
Semoga ini bisa membantu sebagai contoh
sumber
Melempar pengecualian saat pengecualian lain aktif akan menghasilkan pengecualian pertama digantikan oleh pengecualian kedua (nanti).
Berikut adalah beberapa kode yang menggambarkan apa yang terjadi:
sumber
Beberapa bulan yang lalu saya juga menghadapi sesuatu seperti ini,
Untuk mengatasi masalah tersebut saya membuat kelas utilitas seperti
Dan digunakan seperti ini
tetapi jika Anda ingin menggunakan paramater dan mengembalikan tipe itu adalah cerita lain
sumber
Cara pengecualian yang dilontarkan oleh CodeA dan CodeB ditangani adalah sama.
Pengecualian yang dilemparkan ke dalam
finally
blok tidak ada yang spesial, memperlakukannya sebagai pengecualian dengan membuang kode B.sumber
Pengecualian menyebar, dan harus ditangani di tingkat yang lebih tinggi. Jika pengecualian tidak ditangani di tingkat yang lebih tinggi, aplikasi macet. Eksekusi blok "akhirnya" berhenti pada titik di mana pengecualian dilemparkan.
Terlepas dari apakah ada pengecualian atau tidak, blok "akhirnya" dijamin untuk dieksekusi.
Jika blok "akhirnya" dijalankan setelah pengecualian terjadi di blok coba,
dan jika pengecualian itu tidak ditangani
dan jika blok akhirnya melempar pengecualian
Maka pengecualian asli yang terjadi di blok percobaan hilang.
Artikel bagus untuk Detail
sumber
Ini melempar pengecualian;) Anda dapat menangkap pengecualian itu dalam beberapa klausa tangkapan lainnya.
sumber