2009-01-02 202 views
34

我想为所有意外的异常设置一些处理程序,我可能没有在代码中捕获异常。在Program.Main()我用下面的代码:处理未处理的异常问题

AppDomain.CurrentDomain.UnhandledException 
    += new UnhandledExceptionEventHandler(ErrorHandler.HandleException); 

但它没有按预期工作。当我在调试模式下启动应用程序并抛出异常时,它确实调用了处理程序,但之后,Visual Studio中的异常帮助程序弹出,就好像发生异常而没有进行任何处理。我在处理程序中尝试了Application.Exit(),但它并没有工作。

我想达成什么是例外与我的处理程序进行处理,然后将应用程序很好地关闭。有没有其他的方式来做到这一点,或者我用错误的方式使用上面的代码?

回答

27

这是因为你通过Visual Studio在调试模式下运行它。如果您在其他地方发布并安装您的应用程序,则只会处理您的全局异常处理程序。

6

请注意,未处理的异常仍然非常致命;你只能真正使用它来进行日志记录,或者可能是一些仓促的关闭。这个和Application.ThreadException都不能用作错误的全局接收器。

更好的方法是添加适当的处理 - 例如,在你的整个Main()逻辑。请注意,即使这个也无法捕捉到一些例外情况,例如表单加载期间的错误(这尤其令人讨厌 - 您可以使用附加的调试器捕获它们,但并非如此)。

+0

嗯,是的,当然我知道;) – agnieszka 2009-01-02 09:48:45

+0

那么为什么不在他们的主要()? – 2009-01-02 10:05:36

31

通常我使用这样的尝试和捕获所有意想不到的顶级例外。

using System; 

static class Program 
{ 
    [STAThread] 
    static void Main(string[] argv) 
    { 
    try 
    { 
     AppDomain.CurrentDomain.UnhandledException += (sender,e) 
     => FatalExceptionObject(e.ExceptionObject); 

     Application.ThreadException += (sender,e) 
     => FatalExceptionHandler.Handle(e.Exception); 

     // whatever you need/want here 

     Application.Run(new MainWindow()); 
    } 
    catch (Exception huh) 
    { 
     FatalExceptionHandler.Handle(huh); 
    } 
    } 

    static void FatalExceptionObject(object exceptionObject) { 
    var huh = exceptionObject as Exception; 
    if (huh == null) { 
     huh = new NotSupportedException(
     "Unhandled exception doesn't derive from System.Exception: " 
     + exceptionObject.ToString() 
    ); 
    } 
    FatalExceptionHandler.Handle(huh); 
    } 
} 

也许这是你找到有用的东西吗?这个主代码通过一个方法调用来路由所有三种捕获意外的顶级异常的方法。您现在需要的是一个静态类FatalExceptionHandler,其中包括您的顶级异常处理Handle方法。

真的,任何应用开发者都知道有真的只是两两件事要做有:

  1. 显示/记录异常像你认为合适的
  2. 确保你退出/杀申请过程

如果您认为项目二是奇怪的,请记住,我们只费心了真正出色的情况下做到这一点摆在首位。这些东西可能是需要更改您的应用程序以准确解决的错误。任何其他的异常处理 - 功能类型 - 应该在实际的程序代码中降低,捕捉特定类型的异常,这是有道理的,并以有意义的方式处理它们。还有什么应该泡到你的FatalExceptionHandler,使自己已知的,从损坏的状态工作停止可能残废程序

死程序撒谎... ;-)

2

你要找也许什么是Environment.Exit(int errorcode)

1

这种行为是由设计。

但是的解决办法。

要么在处理程序中调用Process.GetCurrentProcess().Kill();,要么就是不要让处理程序结束。

退房的例子:

class Program 
{ 
    void Run() 
    { 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

     Console.WriteLine("Press enter to exit."); 

     do 
     { 
      (new Thread(delegate() 
      { 
       throw new ArgumentException("ha-ha"); 
      })).Start(); 

     } while (Console.ReadLine().Trim().ToLowerInvariant() == "x"); 


     Console.WriteLine("last good-bye"); 
    } 

    int r = 0; 

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Interlocked.Increment(ref r); 
     Console.WriteLine("handled. {0}", r); 
     Console.WriteLine("Terminating " + e.IsTerminating.ToString()); 

     Thread.CurrentThread.IsBackground = true; 
     Thread.CurrentThread.Name = "Dead thread";    

     while (true) 
      Thread.Sleep(TimeSpan.FromHours(1)); 
     //Process.GetCurrentProcess().Kill(); 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine("..."); 
     (new Program()).Run(); 
    } 
} 

这不应该成为例外默认下沉,肯定。

但是这应该完成以优雅地报告异常。