Saya hampir yakin jawabannya adalah YA. Jika saya menggunakan blok Try Akhirnya tetapi tidak menggunakan blok Catch maka pengecualian apa pun AKAN muncul. Benar?
Ada pemikiran tentang latihan secara umum?
Seth
Saya hampir yakin jawabannya adalah YA. Jika saya menggunakan blok Try Akhirnya tetapi tidak menggunakan blok Catch maka pengecualian apa pun AKAN muncul. Benar?
Ada pemikiran tentang latihan secara umum?
Seth
Jawaban:
Ya, itu pasti akan terjadi. Dengan asumsi finally
blok Anda tidak memunculkan pengecualian, tentu saja, dalam hal ini hal itu akan secara efektif "menggantikan" yang semula dilemparkan.
Ada pemikiran tentang latihan secara umum?
Iya. Berhati-hatilah . Saat pemblokiran terakhir Anda berjalan, sangat mungkin blok tersebut berjalan karena pengecualian yang tidak tertangani dan tidak terduga telah dilemparkan . Itu berarti ada sesuatu yang rusak , dan sesuatu yang sama sekali tidak terduga bisa terjadi.
Dalam situasi itu, Anda tidak boleh menjalankan kode pada blok terakhir sama sekali. Kode pada blok terakhir dapat dibangun untuk mengasumsikan bahwa subsistem yang bergantung padanya sehat, padahal sebenarnya mereka bisa sangat rusak. Kode di blok terakhir bisa memperburuk keadaan.
Misalnya, saya sering melihat hal semacam ini:
DisableAccessToTheResource();
try
{
DoSomethingToTheResource();
}
finally
{
EnableAccessToTheResource();
}
Penulis kode ini berpikir, "Saya membuat mutasi sementara pada keadaan dunia; saya perlu mengembalikan keadaan ke keadaan sebelum saya dipanggil". Tapi mari kita pikirkan tentang semua kemungkinan kesalahan ini.
Pertama, akses ke sumber daya sudah bisa dinonaktifkan oleh pemanggil; dalam hal ini, kode ini mengaktifkannya kembali, mungkin sebelum waktunya.
Kedua, jika DoSomethingToTheResource melontarkan pengecualian, apakah hal yang benar untuk dilakukan untuk mengaktifkan akses ke sumber daya ??? Kode yang mengelola sumber daya tiba - tiba rusak . Kode ini mengatakan, pada dasarnya "jika kode manajemen rusak, pastikan bahwa kode lain dapat memanggil kode yang rusak itu secepat mungkin, sehingga bisa juga gagal total ." Sepertinya ini ide yang buruk.
Ketiga, jika DoSomethingToTheResource melontarkan pengecualian, lalu bagaimana kita tahu bahwa EnableAccessToTheResource juga tidak akan menampilkan pengecualian? Apa pun kerusakan yang terjadi, penggunaan sumber daya juga dapat memengaruhi kode pembersihan, dalam hal ini pengecualian asli akan hilang dan masalah akan lebih sulit didiagnosis.
Saya cenderung menulis kode seperti ini tanpa menggunakan blok try-akhirnya:
bool wasDisabled = IsAccessDisabled();
if (!wasDisabled)
DisableAccessToTheResource();
DoSomethingToTheResource();
if (!wasDisabled)
EnableAccessToTheResource();
Sekarang status tidak bermutasi kecuali perlu. Sekarang status penelepon tidak dipusingkan. Dan sekarang, jika DoSomethingToTheResource gagal, maka kami tidak mengaktifkan kembali akses. Kami berasumsi bahwa ada sesuatu yang rusak parah dan tidak mengambil risiko memperburuk situasi dengan mencoba terus menjalankan kode. Biarkan penelepon mengatasi masalahnya, jika mereka bisa.
Jadi, kapan ide yang bagus untuk menjalankan blok terakhir? Pertama, saat pengecualian diharapkan. Misalnya, Anda mungkin berharap bahwa upaya untuk mengunci file mungkin gagal, karena orang lain telah menguncinya. Dalam kasus ini, masuk akal untuk menangkap pengecualian dan melaporkannya kepada pengguna. Dalam hal ini, ketidakpastian tentang apa yang rusak berkurang; Anda tidak mungkin memperburuk keadaan dengan membersihkan.
Kedua, ketika sumber daya yang Anda bersihkan adalah sumber daya sistem yang langka. Misalnya, masuk akal untuk menutup pegangan file di blok akhirnya. (A "menggunakan" tentu saja hanyalah cara lain untuk menulis blok coba-akhirnya.) Konten file mungkin rusak, tetapi tidak ada yang dapat Anda lakukan sekarang. Pegangan file akan ditutup pada akhirnya, jadi mungkin juga lebih cepat daripada nanti.