控制台应用程序中的.NET Global异常处理

问题:我想在控制台应用程序中为未处理的异常定义全局异常处理程序。 在asp.net中,可以在global.asax中定义一个,在windows应用程序/服务中,可以定义如下

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyExceptionHandler);

但是,我怎样才能为控制台应用程序定义全局异常处理程序?
currentDomain似乎不工作(.NET 2.0)?

编辑:

啊,愚蠢的错误。
在VB.NET中,需要在currentDomain前添加“AddHandler”关键字,否则在IntelliSense中不会看到UnhandledException事件...
这是因为VB.NET和C#编译器不同地处理事件处理。


不,这是正确的做法。 这工作完全按照它应该的,你可以从以下工作:

using System;

class Program {
    static void Main(string[] args) {
        System.AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
        throw new Exception("Kaboom");
    }

    static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e) {

        ConsoleColor colorBefore = Console.ForegroundColor;
        Console.ForegroundColor = ConsoleColor.Red;

        Console.WriteLine(e.ExceptionObject.ToString());

        Console.ForegroundColor = colorBefore;

        Console.WriteLine("Press Enter to continue");
        Console.ReadLine();
        Environment.Exit(1);
    }
}

请记住,您无法通过这种方式捕捉由抖动产生的类型和文件加载异常。 它们在您的Main()方法开始运行之前发生。 捕捉这些需要延迟抖动,将有风险的代码移动到另一个方法,并应用[MethodImpl(MethodImplOptions.NoInlining)]属性。


如果您有单线程应用程序,则可以在Main函数中使用简单的try / catch,但是,这并不包括例如在其他线程上可能抛出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");
   }
}

您还需要处理线程的异常:

static void Main(string[] args) {
Application.ThreadException += MYThreadHandler;
}

private void MYThreadHandler(object sender, Threading.ThreadExceptionEventArgs e)
{
    Console.WriteLine(e.Exception.StackTrace);
}

哎呀,对于winforms,对于任何在控制台应用程序中使用的线程,您都必须将其放在try / catch块中。 后台线程遇到未处理的异常不会导致应用程序结束。

链接地址: http://www.djcxy.com/p/50569.html

上一篇: .NET Global exception handler in console application

下一篇: How can I update the current line in a C# Windows Console App?