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):
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void DemoThread()
{
for(int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24 / i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
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:
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("Notified of a thread exception... application is terminating.");
}
static void DemoThread()
{
for(int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24 / i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
Jadi menurut saya, cara paling bersih untuk menanganinya dalam aplikasi konsol adalah memastikan bahwa setiap utas memiliki penangan pengecualian di tingkat root:
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void DemoThread()
{
try
{
for (int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24 / i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception on the other thread");
}
}
Console.ReadLine()
atau gangguan aliran program lainnya. Tetapi yang saya dapatkan adalah pengecualian untuk meningkatkan lagi dan lagi, dan lagi.