AppDomain.UnhandledException Kejadian
Definisi
Penting
Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Terjadi ketika pengecualian tidak tertangkap.
public:
event UnhandledExceptionEventHandler ^ UnhandledException;
public:
virtual event UnhandledExceptionEventHandler ^ UnhandledException;
public event UnhandledExceptionEventHandler? UnhandledException;
public event UnhandledExceptionEventHandler UnhandledException;
[add: System.Security.SecurityCritical]
[remove: System.Security.SecurityCritical]
public event UnhandledExceptionEventHandler UnhandledException;
member this.UnhandledException : UnhandledExceptionEventHandler
[<add: System.Security.SecurityCritical>]
[<remove: System.Security.SecurityCritical>]
member this.UnhandledException : UnhandledExceptionEventHandler
Public Custom Event UnhandledException As UnhandledExceptionEventHandler
Jenis Acara
Penerapan
- Atribut
Contoh
Contoh berikut menunjukkan peristiwa tersebut UnhandledException . Ini mendefinisikan penanganan aktivitas, MyHandler, yang dipanggil setiap kali pengecualian yang tidak tertangani dilemparkan di domain aplikasi default. Kemudian melempar dua pengecualian. Yang pertama ditangani oleh blok coba/tangkap . Yang kedua tidak tertangani dan memanggil MyHandle rutinitas sebelum aplikasi berakhir.
// The example should be compiled with the /clr:pure compiler option.
using namespace System;
using namespace System::Security::Permissions;
public ref class Example
{
private:
static void MyHandler(Object^ sender, UnhandledExceptionEventArgs^ args)
{
Exception^ e = dynamic_cast<Exception^>(args->ExceptionObject);
Console::WriteLine( "MyHandler caught : {0}", e->Message );
Console::WriteLine("Runtime terminating: {0}", args->IsTerminating);
}
public:
[SecurityPermissionAttribute( SecurityAction::Demand, ControlAppDomain = true )]
static void Main()
{
AppDomain^ currentDomain = AppDomain::CurrentDomain;
currentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(Example::MyHandler);
try
{
throw gcnew Exception("1");
}
catch (Exception^ e)
{
Console::WriteLine( "Catch clause caught : {0}\n", e->Message );
}
throw gcnew Exception("2");
}
};
void main()
{
Example::Main();
}
// The example displays the following output:
// Catch clause caught : 1
//
// MyHandler caught : 2
// Runtime terminating: True
//
// Unhandled Exception: System.Exception: 2
// at Example.Main()
// at mainCRTStartup(String[] arguments)
using System;
public class Example
{
public static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
try {
throw new Exception("1");
} catch (Exception e) {
Console.WriteLine("Catch clause caught : {0} \n", e.Message);
}
throw new Exception("2");
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
}
}
// The example displays the following output:
// Catch clause caught : 1
//
// MyHandler caught : 2
// Runtime terminating: True
//
// Unhandled Exception: System.Exception: 2
// at Example.Main()
open System
open System.Security.Permissions
let myHandler _ (args: UnhandledExceptionEventArgs) =
let e = args.ExceptionObject :?> Exception
printfn $"MyHandler caught : {e.Message}"
printfn $"Runtime terminating: {args.IsTerminating}"
[<EntryPoint>]
let main _ =
let currentDomain = AppDomain.CurrentDomain
currentDomain.UnhandledException.AddHandler(UnhandledExceptionEventHandler myHandler)
try
failwith "1"
with e ->
printfn $"Catch clause caught : {e.Message} \n"
failwith "2"
// The example displays the following output:
// Catch clause caught : 1
//
// MyHandler caught : 2
// Runtime terminating: True
//
// Unhandled Exception: System.Exception: 2
// at Example.main()
Module Example
Sub Main()
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler
Try
Throw New Exception("1")
Catch e As Exception
Console.WriteLine("Catch clause caught : " + e.Message)
Console.WriteLine()
End Try
Throw New Exception("2")
End Sub
Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
Dim e As Exception = DirectCast(args.ExceptionObject, Exception)
Console.WriteLine("MyHandler caught : " + e.Message)
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating)
End Sub
End Module
' The example displays the following output:
' Catch clause caught : 1
'
' MyHandler caught : 2
' Runtime terminating: True
'
' Unhandled Exception: System.Exception: 2
' at Example.Main()
Keterangan
Handler mungkin dipanggil beberapa kali jika pengecualian dilemparkan dari utas yang berbeda.
Peristiwa UnhandledException memberikan pemberitahuan tentang pengecualian yang tidak tertangkap. Ini memungkinkan aplikasi untuk mencatat informasi tentang pengecualian sebelum handler default sistem melaporkan pengecualian kepada pengguna dan mengakhiri aplikasi. Jika informasi yang memadai tentang status aplikasi tersedia, tindakan lain dapat dilakukan - seperti menyimpan data program untuk pemulihan nanti. Perhatian disarankan, karena data program dapat rusak ketika pengecualian tidak ditangani. Pengendali juga akan berjalan sambil memegang kunci yang sudah dipegang ketika pengecualian dilemparkan, jadi diperlukan kehati-hatian untuk menghindari menunggu sumber daya lain yang dapat menyebabkan kebuntuan.
Kejadian ini dapat ditangani di domain aplikasi apa pun. Namun, peristiwa belum tentu dimunculkan di domain aplikasi tempat pengecualian terjadi. Pengecualian tidak tertangani hanya jika seluruh tumpukan untuk utas telah diurai tanpa menemukan penangan pengecualian yang sesuai, sehingga tempat pertama peristiwa dapat dilaporkan berada di domain aplikasi tempat utas berasal.
Jika peristiwa UnhandledException ditangani di domain aplikasi default, maka peristiwa tersebut diluncurkan di sana untuk setiap pengecualian yang tidak tertangani di utas mana pun, tanpa peduli domain aplikasi tempat utas tersebut dimulai. Jika utas dimulai di domain aplikasi yang memiliki penanganan aktivitas untuk UnhandledException, peristiwa akan dinaikkan di domain aplikasi tersebut. Jika domain aplikasi tersebut bukan merupakan domain aplikasi default, dan ada juga penanganan peristiwa di domain aplikasi default, peristiwa tersebut dijalankan di kedua domain aplikasi.
Misalnya, utas dimulai di domain aplikasi "AD1", memanggil metode di domain aplikasi "AD2", dan dari sana memanggil metode di domain aplikasi "AD3", di mana ia melemparkan pengecualian. Domain aplikasi pertama di mana peristiwa UnhandledException dapat dipicu adalah "AD1". Jika domain aplikasi tersebut bukan domain aplikasi default, peristiwa juga dapat dinaikkan di domain aplikasi default.
Note
Runtime bahasa umum menangguhkan penghentian thread ketika penangan peristiwa untuk UnhandledException sedang dieksekusi.
Jika penanganan aktivitas memiliki ReliabilityContractAttribute atribut dengan bendera yang sesuai, penanganan aktivitas diperlakukan sebagai wilayah eksekusi yang dibatasi.
Kejadian ini tidak dimunculkan untuk pengecualian yang merusak status proses, seperti luapan tumpukan atau pelanggaran akses, kecuali penanganan aktivitas kritis keamanan dan memiliki HandleProcessCorruptedStateExceptionsAttribute atribut .
Untuk mendaftarkan pengendali acara untuk event ini, Anda harus memiliki izin yang diperlukan, atau SecurityException dilemparkan.
Untuk informasi selengkapnya tentang menangani peristiwa, lihat Menangani dan Meningkatkan Peristiwa.
Peristiwa lain untuk pengecualian yang tidak tertangani
Untuk model aplikasi tertentu, UnhandledException event dapat didahului oleh event lain jika pengecualian yang tidak tertangani terjadi di utas utama aplikasi.
Dalam aplikasi yang menggunakan Formulir Windows, pengecualian yang tidak tertangani di utas aplikasi utama menyebabkan peristiwa Application.ThreadException dipicu. Jika peristiwa ini ditangani, perilaku defaultnya adalah bahwa pengecualian yang tidak tertangani tidak mengakhiri aplikasi, meskipun aplikasi dibiarkan dalam keadaan tidak diketahui. Dalam hal ini, UnhandledException peristiwa tidak dinaikkan. Perilaku ini dapat diubah dengan menggunakan file konfigurasi aplikasi, atau dengan menggunakan metode Application.SetUnhandledExceptionMode untuk mengubah mode sebelum penangan kejadian UnhandledExceptionMode.ThrowExceptionThreadException dikaitkan. Ini hanya berlaku untuk utas aplikasi utama. Peristiwa UnhandledException ini dibangkitkan untuk pengecualian yang tidak tertangani yang dilemparkan di utas lain.
Kerangka kerja aplikasi Visual Basic menyediakan satu lagi peristiwa untuk menangani pengecualian yang tidak tertangani di utas utama aplikasi—peristiwa WindowsFormsApplicationBase.UnhandledException. Kejadian 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 peristiwa ini memiliki ExitApplication properti yang memungkinkan aplikasi untuk terus berjalan, mengabaikan pengecualian yang tidak tertangani (dan meninggalkan aplikasi dalam keadaan tidak diketahui). Dalam hal ini, AppDomain.UnhandledException peristiwa tidak dinaikkan.