Pertanyaan: Saya ingin mendefinisikan pengendali pengecualian global untuk pengecualian yang tidak ditangani dalam aplikasi konsol saya. Di asp.net, seseorang dapat mendefinisikan satu di global.asax, dan di windows aplikasi / layanan, seseorang dapat mendefinisikan seperti di bawah ini
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyExceptionHandler);
Tetapi bagaimana saya bisa mendefinisikan handler pengecualian global untuk aplikasi konsol?
currentDomain tampaknya tidak berfungsi (.NET 2.0)?
Edit:
Argh, kesalahan bodoh.
Di VB.NET, seseorang perlu menambahkan kata kunci "AddHandler" di depan currentDomain, atau orang tidak akan melihat acara UnhandledException di IntelliSense ...
Itu karena kompiler VB.NET dan C # memperlakukan penanganan acara secara berbeda.
sumber
Console.ReadLine()
atau gangguan aliran program lainnya. Tetapi yang saya dapatkan adalah pengecualian untuk meningkatkan lagi dan lagi, dan lagi.Jika Anda memiliki aplikasi single-threaded, Anda dapat menggunakan try / catch sederhana di fungsi Utama, namun, ini tidak mencakup pengecualian yang mungkin dilemparkan di luar fungsi utama, pada utas lainnya, misalnya (seperti yang disebutkan dalam komentar). Kode ini menunjukkan bagaimana pengecualian dapat menyebabkan aplikasi berhenti meskipun Anda mencoba menanganinya di Main (perhatikan bagaimana program keluar dengan anggun jika Anda menekan enter dan memungkinkan aplikasi untuk keluar dengan anggun sebelum pengecualian terjadi, tetapi jika Anda membiarkannya berjalan , ini berakhir dengan sangat tidak senang):
Anda dapat menerima pemberitahuan kapan utas lain membuat pengecualian untuk melakukan pembersihan sebelum aplikasi keluar, tetapi sejauh yang saya tahu, Anda tidak bisa, dari aplikasi konsol, memaksa aplikasi untuk terus berjalan jika Anda tidak menangani pengecualian pada utas dari mana ia dilemparkan tanpa menggunakan beberapa opsi kompatibilitas yang tidak jelas untuk membuat aplikasi berperilaku seperti itu dengan .NET 1.x. Kode ini menunjukkan bagaimana utas utama dapat diberitahu tentang pengecualian yang berasal dari utas lain, tetapi masih akan berakhir dengan sedih:
Jadi menurut saya, cara paling bersih untuk menanganinya dalam aplikasi konsol adalah memastikan bahwa setiap utas memiliki penangan pengecualian di tingkat root:
sumber
Anda juga perlu menangani pengecualian dari utas:
Whoop, maaf itu untuk winforms, untuk setiap utas yang Anda gunakan di aplikasi konsol Anda harus melampirkan di blok try / catch. Utas latar belakang yang menemukan pengecualian tidak ditangani tidak menyebabkan aplikasi berakhir.
sumber
Saya baru saja mewarisi aplikasi konsol VB.NET tua dan perlu menyiapkan Global Exception Handler. Karena pertanyaan ini menyebutkan VB.NET beberapa kali dan ditandai dengan VB.NET, tetapi semua jawaban lain di sini adalah dalam C #, saya pikir saya akan menambahkan sintaks yang tepat untuk aplikasi VB.NET juga.
Saya menggunakan
REM
penanda komentar daripada kutipan tunggal di sini karena Stack Overflow sepertinya menangani sintaks yang lebih baik denganREM
.sumber
Apa yang Anda coba harus bekerja sesuai dengan dokumen MSDN untuk .Net 2.0. Anda juga dapat mencoba coba / tangkap langsung di sekitar titik masuk Anda untuk aplikasi konsol.
Dan sekarang tangkapan Anda akan menangani apa pun yang tidak tertangkap ( di utas utama ). Ini bisa menjadi anggun dan bahkan memulai kembali di tempat itu jika Anda mau, atau Anda bisa membiarkan aplikasi mati dan mencatat pengecualian. Anda akan menambahkan akhirnya jika Anda ingin melakukan pembersihan. Setiap utas akan membutuhkan penanganan tingkat tinggi sendiri yang mirip dengan utas.
Diedit untuk memperjelas poin tentang utas seperti yang ditunjukkan oleh BlueMonkMN dan ditunjukkan secara rinci dalam jawabannya.
sumber