Si tiene una aplicación de un solo subproceso, puede usar un simple try / catch en la función Principal, sin embargo, esto no cubre las excepciones que se pueden lanzar fuera de la función Principal, en otros hilos, por ejemplo (como se señaló en otro comentarios) Este código demuestra cómo una excepción puede hacer que la aplicación finalice a pesar de que trataste de manejarla en Main (observa cómo el programa se cierra correctamente si presionas Intro y permites que la aplicación salga correctamente antes de que ocurra la excepción, pero si dejas que se ejecute , termina bastante infelizmente):
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;
}
}
Puede recibir una notificación de cuándo otro subproceso arroja una excepción para realizar una limpieza antes de que la aplicación salga, pero por lo que puedo decir, desde una aplicación de consola no puede forzar la aplicación a continuar ejecutándose si no maneja la excepción en el hilo desde el que se lanza sin usar algunas opciones de compatibilidad oscuras para que la aplicación se comporte como lo haría con .NET 1.x. Este código demuestra cómo se puede notificar al subproceso principal de las excepciones que provienen de otros subprocesos, pero aún así terminará infelizmente:
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;
}
}
Entonces, en mi opinión, la forma más limpia de manejarlo en una aplicación de consola es asegurarse de que cada hilo tenga un controlador de excepción en el nivel raíz:
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()
ninguna otra perturbación del flujo del programa. Pero lo que obtengo es la excepción que vuelve a aparecer una y otra vez, y otra vez.