Si tiene una aplicación de subproceso único, puede usar un simple try/catch en la función Main, sin embargo, esto no cubre las excepciones que pueden producirse fuera de la función Main, en otros subprocesos, por ejemplo (como se señaló en otros comentarios).Este código demuestra cómo una excepción puede causar que la aplicación finalice aunque haya tratado de manejarla en Main (observe cómo el programa sale con gracia si presiona enter y permite que la aplicación salga con gracia antes de que se produzca la excepción, pero si la deja ejecutar , que termina muy infeliz):
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 cuando otro hilo se produce una excepción para poder realizar algunas limpiar antes se cierra la aplicación, pero por lo que puedo decir, no se puede, desde una aplicación de consola , obligue a la aplicación a continuar ejecutándose si no maneja la excepción en el hilo desde el que se lanza sin utilizar algunas opciones de compatibilidad poco claras para que la aplicación se comporte como lo haría con .NET 1.x. Este código muestra cómo el hilo principal puede ser notificado de excepciones procedentes de otros hilos, pero todavía terminar con tristeza:
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;
}
}
Así que en mi opinión, la forma más limpia de lo manejan en una aplicación de consola es asegurar que cada hilo tiene un manejador de excepciones 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");
}
}
Argh, estúpido error, lo que tenga que añadir AddHandler frente a AppDomain.CurrentDomain para ver "UnhandledException" en VB.NET ... –
lo he implementado usted propuso aquí, pero no quiero salir de la aplicación. Solo quiero iniciar sesión y continuar el proceso (sin 'Console.ReadLine()' o cualquier otra alteración del flujo de programas. Pero lo que obtengo es la excepción que se repite una y otra vez, y de nuevo. –
@SharoRoz Jefri: No puede continuar una vez que obtiene una excepción no controlada. La pila está en mal estado, y esto es terminal. Si tiene un servidor, lo que puede hacer en UnhandledExceptionTrapper es reiniciar el programa con los mismos argumentos de línea de comandos. –