Якщо у вас є однопотоковий додаток, ви можете використовувати просту спробу / ловити в функції Main, однак це не охоплює винятку, які можуть бути викинуті за межі основної функції, наприклад, на інші потоки (як зазначено в інших коментарі). Цей код демонструє, як виняток може призвести до припинення роботи програми, навіть якщо ви намагалися впоратися з нею в Main (зверніть увагу, як програма виходить витончено, якщо натиснути клавішу Enter та дозволити програмі вийти вишукано до появи винятку, але якщо ви дозволите її запуску , він закінчується дуже нещасно):
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;
}
}
Ви можете отримувати сповіщення про те, коли інший потік видає виняток, щоб виконати деяке очищення перед виходом програми, але, наскільки я можу сказати, ви не можете з консольного додатку змусити програму продовжувати працювати, якщо ви не обробляєте виняток на нитку, з якої викидається, не використовуючи деякі незрозумілі параметри сумісності, щоб змусити програму вести себе так, як це було б із .NET 1.x. Цей код демонструє, як основний потік може отримувати повідомлення про винятки, що надходять з інших потоків, але все-таки буде нещасно припинено:
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;
}
}
Отже, на мою думку, найчистіший спосіб обробити це в консольному додатку - це гарантувати, що кожен потік має обробник винятків на рівні кореня:
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()
будь-якого іншого порушення потоку програми. Але я отримую виняток - повторне підвищення знову і знову, і знову.