Если у вас однопоточное приложение, вы можете использовать простую попытку / перехват в функции Main, однако это не распространяется на исключения, которые могут быть выброшены вне функции 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()
каких-либо других нарушений потока программ. Но я получаю повторное повышение исключения снова и снова и снова.