如果您有一个单线程应用程序,您可以在 Main 函数中使用简单的 try/catch,但是,这不包括可能在 Main 函数之外,在其他线程上抛出的异常,例如(如在其他 cmets 中注明)。此代码演示了即使您尝试在 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");
}
}