Praktik Terbaik untuk Penanganan Pengecualian dalam Aplikasi Windows Forms?

118

Saat ini saya sedang dalam proses menulis aplikasi Windows Forms pertama saya. Saya telah membaca beberapa buku C # sekarang jadi saya memiliki pemahaman yang relatif baik tentang fitur bahasa apa yang harus ditangani C # dengan pengecualian. Namun semuanya cukup teoritis jadi yang belum saya dapatkan adalah bagaimana menerjemahkan konsep dasar ke dalam model penanganan pengecualian yang baik dalam aplikasi saya.

Adakah yang ingin berbagi mutiara kebijaksanaan tentang hal ini? Posting kesalahan umum yang Anda lihat yang dilakukan oleh pemula seperti saya, dan saran umum tentang menangani pengecualian dengan cara yang akan membuat aplikasi saya lebih stabil dan kuat.

Hal utama yang saat ini saya coba lakukan adalah:

  • Kapan saya harus mengembalikan pengecualian?
  • Haruskah saya mencoba memiliki mekanisme penanganan kesalahan terpusat?
  • Apakah menangani pengecualian yang mungkin terlempar memiliki performa yang lebih baik dibandingkan dengan pengujian secara pre-emptive seperti apakah file pada disk ada?
  • Haruskah semua kode yang dapat dieksekusi diapit dalam blok coba-tangkap-akhirnya?
  • Adakah saat-saat ketika blok tangkap kosong mungkin dapat diterima?

Semua nasihat diterima dengan rasa syukur!

Jon Artus
sumber

Jawaban:

79

Beberapa bit lagi ...

Anda benar-benar harus memiliki kebijakan penanganan pengecualian terpusat. Ini bisa sesederhana membungkus Main()dalam coba / tangkap, gagal dengan cepat dengan pesan kesalahan yang anggun kepada pengguna. Ini adalah pengendali pengecualian "pilihan terakhir".

Pemeriksaan preemptive selalu benar jika memungkinkan, tetapi tidak selalu sempurna. Misalnya, antara kode tempat Anda memeriksa keberadaan file dan baris berikutnya tempat Anda membukanya, file tersebut mungkin telah dihapus atau beberapa masalah lain dapat menghalangi akses Anda. Anda masih perlu mencoba / menangkap / akhirnya di dunia itu. Gunakan pemeriksaan preemptive dan coba / tangkap / akhirnya yang sesuai.

Jangan pernah "menelan" pengecualian, kecuali dalam kasus yang paling terdokumentasi dengan baik ketika Anda benar-benar yakin secara positif bahwa pengecualian yang dilemparkan itu layak huni. Ini hampir tidak akan pernah terjadi. (Dan jika ya, pastikan Anda hanya menelan kelas pengecualian tertentu - jangan pernah menelan System.Exception.)

Saat membuat perpustakaan (digunakan oleh aplikasi Anda), jangan menelan pengecualian, dan jangan takut untuk membiarkan pengecualian meluap. Jangan lempar ulang kecuali Anda memiliki sesuatu yang berguna untuk ditambahkan. Jangan pernah (di C #) melakukan ini:

throw ex;

Karena Anda akan menghapus tumpukan panggilan. Jika Anda harus melempar ulang (yang terkadang diperlukan, seperti saat menggunakan Blok Penanganan Pengecualian dari Pustaka Perusahaan), gunakan yang berikut ini:

throw;

Pada akhirnya, sebagian besar pengecualian yang diberikan oleh aplikasi yang sedang berjalan harus diekspos di suatu tempat. Mereka tidak boleh diekspos ke pengguna akhir (karena mereka sering berisi data kepemilikan atau berharga), tetapi biasanya dicatat, dengan administrator diberitahu tentang pengecualian. Pengguna dapat disajikan dengan kotak dialog umum, mungkin dengan nomor referensi, untuk mempermudah.

Penanganan pengecualian di .NET lebih merupakan seni daripada sains. Semua orang akan memiliki favorit untuk dibagikan di sini. Ini hanyalah beberapa tip yang saya ambil dengan menggunakan .NET sejak hari pertama, teknik yang telah menyelamatkan daging saya di lebih dari satu kesempatan. Jarak tempuh Anda mungkin berbeda.

John Rudy
sumber
1
Jika seseorang membiarkan pengecualian muncul, bagaimana peneleponnya mengetahui apakah pengecualian tersebut menunjukkan bahwa suatu operasi gagal tetapi sistem pada dasarnya baik-baik saja (misalnya pengguna mencoba membuka file dokumen yang rusak; file tidak dimuat, tetapi semuanya lain harus baik-baik saja), atau apakah itu menunjukkan bahwa CPU sedang terbakar dan seseorang harus keluar secepat mungkin? Sesuatu seperti ArgumentException dapat menunjukkan keduanya, bergantung pada keadaan saat pelemparannya.
supercat
2
@supercat Dengan menulis subkelas khusus ApplicationExceptionuntuk kasus kegagalan tersebut yang seharusnya dapat dibedakan dan ditangani oleh aplikasi.
Matt Enright
@Matt Enright: Tentu saja mungkin untuk menangkap pengecualian sendiri, tetapi saya tidak mengetahui apa pun yang mirip dengan konvensi di mana modul yang menampilkan pengecualian menunjukkan apakah mereka menunjukkan kerusakan negara apa pun di luar apa yang tersirat oleh kegagalan. Idealnya, metode seperti SuperDocument.CreateFromFile () akan berhasil, memunculkan pengecualian CleanFailure, atau memunculkan SomethingReallyBadHappenedException. Sayangnya, kecuali seseorang membungkus semua yang mungkin memunculkan pengecualian dalam blok tangkapnya sendiri, tidak ada cara untuk mengetahui apakah InvalidOperationException ...
supercat
@Matt Enright: ... harus dibungkus dengan CleanFailureException atau SomethingReallyBadHappenedException. Dan membungkus semuanya dalam blok coba-tangkap individu akan mengalahkan seluruh tujuan memiliki pengecualian di tempat pertama.
supercat
2
Saya pikir itu desain perpustakaan yang buruk, untuk menyembunyikan mode kegagalan dengan jenis pengecualian yang tidak akurat. Jangan melempar FileNotFoundException jika yang Anda maksud sebenarnya adalah IOException atau InvalidDataException, karena aplikasi perlu merespons setiap kasus secara berbeda. Hal-hal seperti StackOverflowException atau OutOfMemoryException tidak dapat ditangani secara wajar oleh aplikasi, jadi biarkan saja mereka menggelembung, karena aplikasi yang berperilaku baik memiliki penangan "pilihan terakhir" yang terpusat di tempatnya.
Matt Enright
63

Ada artikel CodeProject kode yang sangat baik di sini . Berikut ini beberapa sorotan:

  • Rencanakan yang terburuk *
  • Periksa lebih awal
  • Jangan percaya data eksternal
  • Satu-satunya perangkat yang dapat diandalkan adalah: video, mouse, dan keyboard.
  • Penulisan juga bisa gagal
  • Kode dengan Aman
  • Jangan melempar Exception baru ()
  • Jangan letakkan informasi pengecualian penting di bidang Pesan
  • Letakkan satu tangkapan (Exception ex) per utas
  • Pengecualian Umum yang tertangkap harus dipublikasikan
  • Log Exception.ToString (); jangan pernah mencatat hanya Exception.Message!
  • Jangan menangkap (Pengecualian) lebih dari sekali per utas
  • Jangan pernah menelan pengecualian
  • Kode pembersihan harus diletakkan di blok terakhir
  • Gunakan "menggunakan" di mana saja
  • Jangan mengembalikan nilai khusus pada kondisi kesalahan
  • Jangan gunakan pengecualian untuk menunjukkan tidak adanya sumber daya
  • Jangan gunakan penanganan pengecualian sebagai cara untuk mengembalikan informasi dari suatu metode
  • Gunakan pengecualian untuk kesalahan yang tidak boleh diabaikan
  • Jangan hapus jejak tumpukan saat melempar kembali pengecualian
  • Hindari mengubah pengecualian tanpa menambahkan nilai semantik
  • Pengecualian harus ditandai [Dapat berseri]
  • Jika ragu, jangan Tegaskan, berikan Pengecualian
  • Setiap kelas pengecualian harus memiliki setidaknya tiga konstruktor asli
  • Berhati-hatilah saat menggunakan peristiwa AppDomain.UnhandledException
  • Jangan menemukan kembali roda
  • Jangan gunakan Penanganan Kesalahan Tidak Terstruktur (VB.Net)
Mikha
sumber
3
Maukah Anda menjelaskan sedikit lebih jauh tentang hal ini kepada saya? "Jangan gunakan pengecualian untuk menunjukkan tidak adanya sumber daya" Saya tidak begitu yakin saya memahami alasan di baliknya. Juga hanya sebuah komentar: jawaban ini tidak menjelaskan "mengapa" sama sekali. Saya tahu ini berusia 5 tahun tetapi masih sedikit mengganggu saya
Rémi
Tautan ke artikel yang direferensikan telah kedaluwarsa. Proyek Kode menyarankan bahwa artikel tersebut mungkin telah dipindahkan ke sini .
DavidRR
15

Perhatikan bahwa Windows Forms memiliki mekanisme penanganan pengecualiannya sendiri. Jika tombol dalam formulir diklik dan penangannya melontarkan pengecualian yang tidak tertangkap dalam penangan, Formulir Windows akan menampilkan Dialog Pengecualian Tak Tertangani sendiri.

Untuk mencegah Unhandled Exception Dialog ditampilkan dan menangkap pengecualian tersebut untuk logging dan / atau untuk menyediakan dialog error Anda sendiri, Anda dapat melampirkan ke event Application.ThreadException sebelum panggilan ke Application.Run () dalam metode Main () Anda.

pengguna95680
sumber
Terima kasih atas saran ini, saya terlambat mempelajarinya, saya baru saja memverifikasi di linqpad, berfungsi seperti yang diharapkan, delegasinya adalah: void Form1_UIThreadException (pengirim objek, ThreadExceptionEventArgs t) Sumber bagus lainnya tentang topik ini adalah richnewman.wordpress.com/2007/ 04/08 /… Untuk keseluruhan penanganan pengecualian yang tidak tertangani: AppDomain.UnhandledException adalah untuk pengecualian yang tidak tertangani yang dilempar dari non-main-UI-thread.
zhaorufei
14

Sejauh ini, semua saran yang diposting di sini bagus dan patut diperhatikan.

Satu hal yang ingin saya perluas adalah pertanyaan Anda "Apakah menangani pengecualian yang mungkin muncul memiliki performa yang lebih baik dibandingkan dengan pengujian sebelumnya seperti apakah ada file di disk?"

Aturan praktis yang naif adalah "blok coba / tangkap itu mahal." Itu tidak benar. Mencoba tidaklah mahal. Penangkapannya, di mana sistem harus membuat objek Exception dan memuatnya dengan pelacakan tumpukan, itu mahal. Ada banyak kasus di mana pengecualiannya, yah, cukup luar biasa sehingga tidak masalah untuk membungkus kode dalam blok coba / tangkap.

Misalnya, jika Anda mengisi Kamus, ini:

try
{
   dict.Add(key, value);
}
catch(KeyException)
{
}

sering kali lebih cepat daripada melakukan ini:

if (!dict.ContainsKey(key))
{
   dict.Add(key, value);
}

untuk setiap item yang Anda tambahkan, karena pengecualian hanya dilemparkan saat Anda menambahkan kunci duplikat. (Kueri agregat LINQ melakukan ini.)

Dalam contoh yang Anda berikan, saya akan menggunakan coba / tangkap hampir tanpa berpikir. Pertama, hanya karena file tersebut ada saat Anda memeriksanya, bukan berarti file itu akan ada saat Anda membukanya, jadi Anda harus benar-benar menangani pengecualian tersebut.

Kedua, dan saya pikir yang lebih penting, kecuali a) proses Anda membuka ribuan file dan b) kemungkinan file yang coba dibuka tidak ada tidak terlalu rendah, kinerja hit untuk membuat pengecualian bukanlah sesuatu yang Anda ' akan memperhatikan. Secara umum, ketika program Anda mencoba membuka file, program itu hanya mencoba membuka satu file. Itu adalah kasus di mana menulis kode yang lebih aman hampir pasti akan lebih baik daripada menulis kode secepat mungkin.

Robert Rossney
sumber
3
dalam kasus dict, Anda dapat melakukan: dict[key] = valueyang seharusnya secepat jika tidak lebih cepat ..
nawfal
9

Berikut beberapa pedoman yang saya ikuti

  1. Fail-Fast: Ini lebih merupakan panduan pembuatan pengecualian, Untuk setiap asumsi yang Anda buat dan setiap parameter yang Anda masukkan ke suatu fungsi lakukan pemeriksaan untuk memastikan bahwa Anda memulai dengan data yang benar dan asumsi Anda Pembuatannya benar. Pemeriksaan khas termasuk, argumen bukan nol, argumen dalam kisaran yang diharapkan, dll.

  2. Saat melempar ulang, pertahankan pelacakan tumpukan - Ini berarti menggunakan lemparan saat melempar ulang alih-alih melempar Exception () baru. Atau jika Anda merasa bahwa Anda dapat menambahkan lebih banyak informasi, maka bungkus pengecualian asli sebagai pengecualian dalam. Tetapi jika Anda menangkap pengecualian hanya untuk mencatatnya maka pasti gunakan lemparan;

  3. Jangan menangkap pengecualian yang tidak dapat Anda tangani, jadi jangan khawatir tentang hal-hal seperti OutOfMemoryException karena jika terjadi, Anda tidak akan dapat berbuat banyak.

  4. Lakukan hook penangan pengecualian global dan pastikan untuk mencatat informasi sebanyak mungkin. Untuk winforms, kaitkan appdomain dan thread peristiwa pengecualian yang tidak tertangani.

  5. Performa sebaiknya hanya dipertimbangkan saat Anda menganalisis kode dan melihat bahwa hal itu menyebabkan kemacetan performa, secara default mengoptimalkan keterbacaan dan desain. Jadi tentang pertanyaan asli Anda pada pemeriksaan keberadaan file, saya akan mengatakan itu tergantung, Jika Anda dapat melakukan sesuatu tentang file yang tidak ada di sana, maka ya lakukan itu, periksa sebaliknya jika semua yang akan Anda lakukan adalah melempar pengecualian jika file itu tidak ada maka saya tidak mengerti intinya.

  6. Pasti ada saat-saat ketika blok tangkapan kosong diperlukan, saya pikir orang yang mengatakan sebaliknya tidak bekerja pada basis kode yang telah berevolusi selama beberapa rilis. Tetapi mereka harus diberi komentar dan ditinjau untuk memastikan bahwa mereka benar-benar dibutuhkan. Contoh paling umum adalah pengembang menggunakan try / catch untuk mengonversi string menjadi integer daripada menggunakan ParseInt ().

  7. Jika Anda mengharapkan pemanggil kode Anda untuk dapat menangani kondisi kesalahan, maka buat pengecualian khusus yang merinci situasi yang tidak dapat dikecualikan dan memberikan informasi yang relevan. Jika tidak, cukup gunakan jenis pengecualian bawaan sebanyak mungkin.

Sijin
sumber
Apa gunanya mengaitkan appdomain dan thread unhandled exception handler? Jika Anda hanya menggunakan Appdomain.UnhandledException, bukankah itu yang paling umum yang akan menangkap semuanya?
Quagmire
Apakah yang Anda maksud menangani Application.ThreadExceptionacara saat Anda mereferensikan acara "untaian pengecualian yang tidak ditangani "?
Jeff B
4

Saya suka filosofi tidak menangkap apa pun yang tidak ingin saya tangani, apa pun arti penanganannya dalam konteks khusus saya.

Saya benci jika saya melihat kode seperti:

try
{
   // some stuff is done here
}
catch
{
}

Saya telah melihat ini dari waktu ke waktu dan cukup sulit untuk menemukan masalah ketika seseorang 'memakan' pengecualian tersebut. Seorang rekan kerja saya melakukan ini dan cenderung berakhir menjadi kontributor arus masalah.

Saya membuang kembali jika ada sesuatu yang kelas khusus saya perlu lakukan sebagai tanggapan atas pengecualian tetapi masalahnya perlu digelembungkan untuk bagaimanapun disebut metode di mana itu terjadi.

Saya pikir kode harus ditulis secara proaktif dan pengecualian harus untuk situasi luar biasa, bukan untuk menghindari pengujian untuk kondisi.

itsmatt
sumber
@Kiquen Maaf saya agak tidak jelas. Yang saya maksud: Jangan lakukan tangkapan kosong seperti itu, sebagai gantinya tambahkan penangan ke Dispatcher.UnhandledException , dan tambahkan setidaknya log sehingga tidak dimakan tanpa remah roti :) Tetapi kecuali Anda memiliki persyaratan komponen diam, Anda harus selalu menyertakan pengecualian ke dalam desain Anda. Lempar ketika mereka perlu dilempar, buat kontrak yang jelas untuk Anda Antarmuka / API / Kelas apa pun.
LuckyLikey
4

Saya baru saja keluar tetapi akan memberi Anda penjelasan singkat tentang di mana harus menggunakan penanganan pengecualian. Saya akan mencoba untuk membahas poin Anda yang lain ketika saya kembali :)

  1. Periksa secara eksplisit untuk semua kondisi kesalahan yang diketahui *
  2. Tambahkan coba / tangkap di sekitar kode jika Anda tidak yakin apakah Anda dapat menangani semua kasus
  3. Tambahkan coba / tangkap di sekitar kode jika antarmuka .NET yang Anda panggil membuat pengecualian
  4. Tambahkan coba / tangkap di sekitar kode jika melewati ambang kompleksitas untuk Anda
  5. Tambahkan percobaan / tangkap di sekitar kode jika untuk pemeriksaan kewarasan: Anda menyatakan INI HARUS TIDAK PERNAH TERJADI
  6. Sebagai aturan umum, saya tidak menggunakan pengecualian sebagai pengganti kode pengembalian. Ini bagus untuk .NET, tapi tidak untuk saya. Saya memiliki pengecualian (hehe) untuk aturan ini, itu tergantung pada arsitektur aplikasi yang Anda kerjakan juga.

*Dengan alasan. Tidak perlu memeriksa untuk melihat apakah sinar kosmik mengenai data Anda menyebabkan beberapa bit terbalik. Memahami apa yang "masuk akal" adalah keterampilan yang diperoleh seorang insinyur. Sulit untuk diukur, namun mudah untuk dipahami. Artinya, saya dapat dengan mudah menjelaskan mengapa saya menggunakan coba / tangkap dalam contoh tertentu, namun saya sulit sekali untuk mengilhami orang lain dengan pengetahuan yang sama ini.

I untuk satu cenderung menjauhi arsitektur berbasis pengecualian. try / catch tidak memiliki hit kinerja seperti itu, klik masuk ketika pengecualian dilemparkan dan kode mungkin harus berjalan naik beberapa tingkat tumpukan panggilan sebelum sesuatu menanganinya.

pezi_pink_squirrel
sumber
4

Aturan emas yang telah dicoba untuk dipegang adalah menangani pengecualian sedekat mungkin dengan sumbernya.

Jika Anda harus melempar ulang pengecualian, coba tambahkan, melempar kembali FileNotFoundException tidak banyak membantu, tetapi dengan melontarkan ConfigurationFileNotFoundException, hal itu akan memungkinkannya ditangkap dan ditindaklanjuti di suatu tempat di rantai.

Aturan lain yang saya coba ikuti adalah tidak menggunakan try / catch sebagai bentuk alur program, jadi saya memverifikasi file / koneksi, memastikan objek telah dimulai, dll .. sebelum menggunakannya. Coba / tangkap harus untuk Pengecualian, hal-hal yang tidak dapat Anda kendalikan.

Sedangkan untuk blok catch kosong, jika Anda melakukan sesuatu yang penting dalam kode yang menghasilkan pengecualian, Anda harus membuang pengecualian tersebut minimal. Jika tidak ada konsekuensi dari kode yang melemparkan pengecualian tidak berjalan mengapa Anda menulisnya di tempat pertama.


sumber
"Aturan emas" ini paling banter.
Evan Harper
3

Anda bisa menjebak acara ThreadException.

  1. Pilih proyek Aplikasi Windows di Solution Explorer.

  2. Buka file Program.cs yang dihasilkan dengan mengklik dua kali di atasnya.

  3. Tambahkan baris kode berikut ke bagian atas file kode:

    using System.Threading;
  4. Dalam metode Main (), tambahkan berikut ini sebagai baris pertama metode:

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
  5. Tambahkan yang berikut di bawah metode Main ():

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        // Do logging or whatever here
        Application.Exit();
    }
  6. Tambahkan kode untuk menangani pengecualian yang tidak tertangani dalam event handler. Pengecualian apa pun yang tidak ditangani di mana pun dalam aplikasi ditangani oleh kode di atas. Paling umum, kode ini harus mencatat kesalahan dan menampilkan pesan kepada pengguna.

refence: https://blogs.msmvps.com/deborahk/global-exception-handler-winforms/

Omid-RH
sumber
@Kiquenet maaf, saya tidak tahu tentang VB
Omid-RH
2

Pengecualian itu mahal tapi perlu. Anda tidak perlu membungkus semuanya dalam try catch tetapi Anda perlu memastikan bahwa pengecualian selalu tertangkap pada akhirnya. Sebagian besar tergantung pada desain Anda.

Jangan lempar ulang jika membiarkan pengecualian meningkat juga akan berhasil. Jangan biarkan kesalahan berlalu begitu saja.

contoh:

void Main()
{
  try {
    DoStuff();
  }
  catch(Exception ex) {
    LogStuff(ex.ToString());
  }

void DoStuff() {
... Stuff ...
}

Jika DoStuff mengalami kesalahan, Anda pasti menginginkannya untuk ditebus. Pengecualian akan dilemparkan ke main dan Anda akan melihat rangkaian kejadian di jejak tumpukan ex.

Echostorm
sumber
1

Kapan saya harus mengembalikan pengecualian?

Di mana-mana, kecuali metode pengguna akhir ... seperti penangan klik tombol

Haruskah saya mencoba memiliki mekanisme penanganan kesalahan terpusat?

Saya menulis file log ... cukup mudah untuk aplikasi WinForm

Apakah menangani pengecualian yang mungkin terlempar memiliki performa yang lebih baik dibandingkan dengan pengujian secara pre-emptive seperti apakah file pada disk ada?

Saya tidak yakin tentang ini, tetapi saya yakin ini adalah praktik yang baik untuk memberikan pengecualian ... Maksud saya, Anda dapat bertanya apakah file itu ada dan jika tidak menampilkan FileNotFoundException

Haruskah semua kode yang dapat dieksekusi diapit dalam blok coba-tangkap-akhirnya?

yeap

Adakah saat-saat ketika blok tangkap kosong mungkin dapat diterima?

Ya, katakanlah Anda ingin menunjukkan tanggal, tetapi Anda tidak tahu bagaimana tanggal itu disimpan (hh / bb / tttt, bb / hh / tttt, dll) Anda coba tp parse tetapi jika gagal, lanjutkan saja .. Jika tidak relevan bagi Anda ... Saya akan mengatakan ya, ada

sebagomez
sumber
1

Satu hal yang saya pelajari dengan sangat cepat adalah untuk benar-benar menyertakan setiap potongan kode yang berinteraksi dengan apa pun di luar aliran program saya (yaitu Sistem File, Panggilan Database, Input Pengguna) dengan blok coba-tangkap. Try-catch dapat menyebabkan performa yang buruk, tetapi biasanya di tempat-tempat ini dalam kode Anda hal itu tidak akan terlihat dan akan terbayar dengan sendirinya dengan aman.

Saya telah menggunakan blok-tangkap kosong di tempat-tempat di mana pengguna mungkin melakukan sesuatu yang sebenarnya tidak "salah", tetapi itu dapat membuat pengecualian ... contoh yang terlintas dalam pikiran ada di GridView jika pengguna DoubleCLicks tempat penampung abu-abu sel di kiri atas itu akan mengaktifkan acara CellDoubleClick, tetapi sel tersebut bukan milik sebuah baris. Dalam hal ini, Anda tidak benar-benar perlu mengirim pesan tetapi jika Anda tidak menangkapnya, itu akan menimbulkan kesalahan pengecualian yang tidak tertangani kepada pengguna.

BKimmel
sumber
1

Saat melempar kembali pengecualian, kata kunci melempar dengan sendirinya. Ini akan membuang pengecualian yang tertangkap dan masih dapat menggunakan pelacakan tumpukan untuk melihat dari mana asalnya.

Try
{
int a = 10 / 0;
}
catch(exception e){
//error logging
throw;
}

melakukan ini akan menyebabkan pelacakan tumpukan berakhir di pernyataan catch. (hindari ini)

catch(Exception e)
// logging
throw e;
}
Brad8118
sumber
apakah ini masih berlaku untuk versi terbaru .NET Framework dan .NET Core?
LuckyLikey
1

n pengalaman saya, saya merasa cocok untuk menangkap pengecualian ketika saya tahu saya akan membuatnya. Misalnya ketika saya berada di aplikasi web dan saya melakukan Response.Redirect, saya tahu saya akan mendapatkan System.ThreadAbortException. Karena memang disengaja saya hanya menangkap untuk jenis tertentu dan menelannya saja.

try
{
/*Doing stuff that may cause an exception*/
Response.Redirect("http:\\www.somewhereelse.com");
}
catch (ThreadAbortException tex){/*Ignore*/}
catch (Exception ex){/*HandleException*/}
Jeff Keslinke
sumber
1

Saya sangat setuju dengan aturan:

  • Jangan biarkan kesalahan berlalu begitu saja.

Alasannya adalah:

  • Saat pertama kali menulis kode, kemungkinan besar Anda tidak akan memiliki pengetahuan penuh tentang kode pihak ketiga, perjanjian FCL .NET, atau kontribusi terbaru rekan kerja Anda. Pada kenyataannya, Anda tidak dapat menolak untuk menulis kode sampai Anda mengetahui setiap kemungkinan pengecualian dengan baik. Begitu
  • Saya terus-menerus menemukan bahwa saya menggunakan try / catch (Exception ex) hanya karena saya ingin melindungi diri saya dari hal-hal yang tidak diketahui, dan, seperti yang Anda perhatikan, saya menangkap Exception, bukan yang lebih spesifik seperti OutOfMemoryException, dll. Dan, saya selalu membuat pengecualian yang muncul ke saya (atau QA) oleh ForceAssert.AlwaysAssert (false, ex.ToString ());

ForceAssert.AlwaysAssert adalah cara pribadi saya untuk Trace.Assert terlepas dari apakah makro DEBUG / TRACE ditentukan.

Siklus pengembangan mungkin: Saya melihat dialog Assert yang jelek atau orang lain mengeluh kepada saya tentang hal itu, lalu saya kembali ke kode dan mencari tahu alasan untuk mengajukan pengecualian dan memutuskan bagaimana memprosesnya.

Dengan cara ini saya dapat menuliskan kode MY dalam waktu singkat dan melindungi saya dari domain yang tidak dikenal, tetapi selalu diperhatikan jika terjadi hal-hal abnormal, dengan cara ini sistem menjadi aman dan lebih aman.

Saya tahu banyak dari Anda tidak akan setuju dengan saya karena pengembang harus mengetahui setiap detail kodenya, terus terang, saya juga seorang purist di masa lalu. Tapi sekarang saya belajar bahwa kebijakan di atas lebih pragmatis.

Untuk kode WinForms, aturan emas yang selalu saya patuhi adalah:

  • Selalu coba / tangkap (Exception) kode event handler Anda

ini akan melindungi UI Anda agar selalu dapat digunakan.

Untuk kinerja hit, penalti kinerja hanya terjadi ketika kode mencapai tangkapan, menjalankan kode percobaan tanpa pengecualian aktual yang dimunculkan tidak berpengaruh signifikan.

Pengecualian harus terjadi dengan sedikit kesempatan, jika tidak maka bukan pengecualian.

zhaorufei
sumber
-1

Anda harus memikirkan pengguna. Aplikasi crash adalah terakhirhal yang diinginkan pengguna. Oleh karena itu, setiap operasi yang dapat gagal harus memiliki blok coba tangkap di tingkat ui. Tidak perlu menggunakan try catch di setiap metode, tetapi setiap kali pengguna melakukan sesuatu, ia harus dapat menangani pengecualian umum. Itu sama sekali tidak membebaskan Anda dari memeriksa semuanya untuk mencegah pengecualian pada kasus pertama, tetapi tidak ada aplikasi kompleks tanpa bug dan OS dapat dengan mudah menambahkan masalah yang tidak terduga, oleh karena itu Anda harus mengantisipasi hal yang tidak terduga dan memastikan jika pengguna ingin menggunakannya operasi tidak akan ada kehilangan data karena aplikasi mogok. Tidak perlu pernah membiarkan aplikasi Anda mogok, jika Anda menemukan pengecualian, itu tidak akan pernah dalam keadaan tidak pasti dan pengguna SELALU merasa tidak nyaman oleh kerusakan. Meskipun pengecualian ada di tingkat paling atas, tidak mogok berarti pengguna dapat dengan cepat mereproduksi pengecualian atau setidaknya merekam pesan kesalahan dan oleh karena itu sangat membantu Anda untuk memperbaiki masalah. Tentu lebih dari sekadar mendapatkan pesan kesalahan sederhana dan kemudian hanya melihat dialog kesalahan jendela atau sesuatu seperti itu.

Itulah mengapa Anda TIDAK PERNAH menjadi sombong dan berpikir bahwa aplikasi Anda tidak memiliki bug, itu tidak dijamin. Dan ini adalah upaya yang sangat kecil untuk membungkus beberapa blok coba tangkap tentang kode yang sesuai dan menampilkan pesan kesalahan / mencatat kesalahan.

Sebagai pengguna, saya pasti sangat kesal setiap kali alis atau aplikasi kantor atau apa pun mogok. Jika pengecualian sangat tinggi sehingga aplikasi tidak dapat melanjutkan, lebih baik menampilkan pesan itu dan memberi tahu pengguna apa yang harus dilakukan (mulai ulang, perbaiki beberapa pengaturan os, laporkan bug, dll.) Daripada hanya crash dan hanya itu.

Terry Bogard
sumber
Dapatkah Anda mencoba menulis jawaban tidak seperti kata-kata kasar dan sebaliknya mencoba lebih spesifik dan mencoba membuktikan maksud Anda? Lihat juga Bagaimana Menjawab .
LuckyLikey