Apa perbedaan antara Application.ThreadException dan AppDomain.CurrentDomain.UnhandledException?

107

Baiklah, ini yang mudah:

  • Apa perbedaan antara Application.ThreadExceptiondan
    AppDomain.CurrentDomain.UnhandledException?

  • Apakah saya perlu menangani keduanya?

Terima kasih!

JohnIdol
sumber

Jawaban:

98

Application.ThreadException dikhususkan untuk Formulir Windows. Winforms menjalankan penangan peristiwa sebagai tanggapan atas pesan yang dikirim kepadanya oleh Windows. Acara Klik misalnya, saya yakin Anda mengenal mereka. Jika penangan kejadian seperti itu melempar pengecualian maka ada penghentian di dalam loop pesan Winforms yang menangkap pengecualian itu.

Backstop tersebut mengaktifkan peristiwa Application.ThreadException . Jika Anda tidak menimpanya, pengguna akan mendapatkan ThreadExceptionDialog . Yang memungkinkan dia untuk mengabaikan pengecualian dan tetap menjalankan program Anda. Bukan ide yang bagus btw.

Anda bisa menonaktifkan perilaku ini dengan memanggil Application.SetUnhandledExceptionMode () dalam metode Main () di Program.cs. Tanpa backstop itu, hal yang biasa terjadi ketika utas mati karena pengecualian yang tidak tertangani: AppDomain.UnhandledException diaktifkan dan program dihentikan.

Fwiw: "ThreadException" adalah pilihan nama yang sangat buruk. Ini tidak ada hubungannya dengan utas.

Hans Passant
sumber
Dan bagaimana menghentikan aplikasi WinForms agar tidak mogok saat terjadinya Application.ThreadException. Saya mengajukan pertanyaan untuk ini [di sini ] dengan kode C # kecil saya.
Mahesha999
2
Saya selalu membacanya sebagai pengecualian utas aplikasi, mengingat bahwa bentuk win terikat pada satu utas.
Gusdor
36

Dari sumber :

Dalam aplikasi yang menggunakan Formulir Windows, pengecualian tidak tertangani di utas aplikasi utama menyebabkan Application.ThreadException acara dimunculkan. Jika acara ini ditangani, perilaku default adalah bahwa pengecualian yang tidak tertangani tidak menghentikan aplikasi, meskipun aplikasi dibiarkan dalam keadaan tidak diketahui. Dalam hal ini, UnhandledException acara tidak dimunculkan. Perilaku ini dapat diubah dengan menggunakan file konfigurasi aplikasi, atau dengan menggunakan Application.SetUnhandledExceptionModemetode untuk mengubah mode UnhandledExceptionMode.ThrowExceptionsebelum ThreadException event handler dihubungkan. Ini hanya berlaku untuk utas aplikasi utama. The UnhandledException event dimunculkan untuk pengecualian tertangani dilemparkan benang lain.

Dimulai dengan Visual Studio 2005 , kerangka aplikasi Visual Basic menyediakan acara lain untuk pengecualian ditangani di thread aplikasi utama - WindowsFormsApplicationBase.UnhandledException. Peristiwa ini memiliki objek argumen peristiwa dengan nama yang sama dengan objek argumen peristiwa yang digunakan oleh AppDomain.UnhandledException, tetapi dengan properti yang berbeda. Secara khusus, objek argumen acara ini memiliki ExitApplicationproperti yang memungkinkan aplikasi untuk terus berjalan, mengabaikan pengecualian yang tidak tertangani (dan membiarkan aplikasi dalam keadaan tidak diketahui). Dalam kasus tersebut, peristiwa AppDomain.UnhandledException tidak dimunculkan.

Application.ThreadExceptiondapat ditangkap dan aplikasi dapat dilanjutkan (secara umum bukan ide yang bagus, tetapi untuk aplikasi seperti menjalankan beberapa tindakan secara berkala ini adalah solusi yang baik).

Untuk menangkap pengecualian yang terjadi di utas yang tidak dibuat dan dimiliki oleh Windows Forms, gunakan file AppDomain.UnhandledException. Ini memungkinkan aplikasi untuk mencatat informasi tentang pengecualian sebelum penangan default sistem melaporkan pengecualian kepada pengguna dan menghentikan aplikasi.
Penanganan pengecualian ini tidak mencegah aplikasi untuk dihentikan.
Maksimum yang bisa dilakukan (data program bisa rusak jika pengecualian tidak ditangani) adalah menyimpan data program untuk pemulihan nanti. Setelah itu domain aplikasi dibongkar dan aplikasi dihentikan.

Dimulai dengan .NET 4 , peristiwa ini tidak dimunculkan untuk pengecualian yang merusak status proses, seperti tumpukan overflows atau pelanggaran akses, kecuali pengendali peristiwa penting keamanan dan memiliki HandleProcessCorruptedStateExceptionsAttribute atribut.

Untuk lebih jelasnya, lihat MSDN .

serhio
sumber
18

Oke - Saya memilikinya di depan saya, sedikit kode dari msdn ini cukup jelas:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}
JohnIdol
sumber
3
ini berbeda dengan jawaban serhio yang lain ketika dia mengatakan: UnhandledExceptionMode.ThrowException harus disetel sebelum pengendali kejadian ThreadException dihubungkan. Tidak yakin apakah urutannya benar-benar penting ...
Davide Piras
@DavidePiras ya, dan ada sesuatu yang lebih suram. SetUnhandledException tampaknya tidak membuat perbedaan dalam kasus saya.
nawfal
0

Masalahnya adalah, ThreadExceptionterjadi karena masalah dengan utas Anda, Unhandled Exceptionini dipecat jika Anda membuat kode pengecualian yang tidak ditangani.

Cara termudah untuk menyebabkan yang kedua adalah dengan membuat aplikasi tanpa mencoba ... menangkap blok dan membuat pengecualian.

Sekarang jika Anda membutuhkan asuransi, Anda dapat menangani keduanya, namun jika Anda menangkap dan menangani Anda exceptionsdengan benar maka Anda tidak memerlukan UnhandledExceptionpawang karena ini seperti menangkap semua.

Joshua Cauble
sumber
terima kasih - yang tidak terlalu saya jelaskan adalah jika menangani UnhandledException saya juga akan menangkap ThreadException - yang tampaknya tidak demikian
JohnIdol