处理未处理的exception问题

我想为所有意外的exception设置一些处理程序,我可能不会在代码中捕获这些exception。 在Program.Main()我用下面的代码:

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

但是没有按照我的预期工作。 当我在debugging模式下启动应用程序并抛出一个exception时,它确实调用了处理程序,但之后,Visual Studio中的exception帮助程序popup,好像发生的exception没有任何处理。 我在处理程序内部尝试了Application.Exit(),但是它没有工作。

我想实现的是,exception处理与我的处理程序,然后应用程序closures很好。 有没有其他的方法来做到这一点,或者我用错误的方式使用上面的代码?

这是因为你在Debug模式下通过Visual Studio运行它。 如果你在别的地方发布和安装你的应用程序,那么只有你的全局exception处理程序将被处理。

通常我使用这样的东西来尝试捕获所有意想不到的顶级exception。

 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); } } 

也许这也是你觉得有帮助的吗? 这个主代码通过一个方法调用来路由所有三种捕获意外的顶级exception的方法。 您现在需要的是一个静态类FatalExceptionHandler ,它包含Handle方法中的顶级exception处理。

实际上,任何应用程序开发人员都知道这里只有两件事情要做:

  1. 显示/logging你认为合适的exception
  2. 确保你退出/closures应用程序进程

如果你觉得第二项是奇怪的,那么记住,我们只是为了在非常特殊的情况下做这个事情。 这些东西可能是需要改变你的应用程序才能准确解决的错误。 任何其他的exception处理 – 函数types – 应该在实际的程序代码中降低,捕捉特定types的exception,这是有道理的,并以合理的方式处理它们。 其他任何东西都应该冒泡到你的FatalExceptionHandler来使自己知道,并停止可能的残缺的程序从损坏的状态工作

死的程序不告诉谎言; 😉

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

更好的方法是添加适当的处理 – 例如,围绕整个Main()逻辑。 请注意,即使不能捕获一些例外,例如在表单加载过程中的错误(这尤其令人讨厌 – 你可以用附加的debugging器捕获它们,但不是没有)。

也许你正在寻找的是Environment.Exit(int errorcode)

这种行为是通过devise。

但有一个解决方法。

要么你调用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(); } } 

当然,这不应该是例外的默认汇。

但是应该这样来优雅地报告exception。