【问题标题】:A generic function that catches all the crashes捕获所有崩溃的通用函数
【发布时间】:2014-08-21 08:16:53
【问题描述】:

我有一个 WPF 应用程序。

我希望应用程序有一个通用函数来捕获不在 try-catch 块中的所有崩溃。应用程序不应崩溃并停止工作。相反,它应该重新启动以尝试再次运行。如果事实证明该应用程序真的搞砸了,它不应该进入无休止的重启循环。

我尝试使用 AppDomain.UnhandledExceptionHandler,它确实捕获了抛出的异常,但是在执行该方法之后 - 程序仍然崩溃。

有没有办法做到这一点?

【问题讨论】:

  • 为什么不阻止异常发生而不是让它发生并尝试重新启动它?当然,有些例外是无法避免的,但只有少数例外。在这些地方添加异常处理。
  • 我相信没有人能如此聪明地编写 100% 容易出错的代码,因此以用户友好的方式处理一小部分未处理的异常是很好的。
  • AppDomain.UnhandledExceptionHandler 让您有机会在退出程序之前记录未处理的异常以进行调试,而不是避免崩溃。
  • @chris 我明白了。这就是我在问题中实际解释的内容。

标签: c# wpf exception-handling


【解决方案1】:

这对我来说效果很好:

  Application.Current.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(AppDispatcherUnhandledException);

  void AppDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
  {
        string message = e.Exception.Message;
        ...

要重新启动 WPF 应用程序,我使用 Windows.Forms 库:

System.Windows.Forms.Application.Restart();
Application.Current.Shutdown();

【讨论】:

    【解决方案2】:

    试试:

        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomain_UnhandledException);
    
    
        // Catch-all exception handler
        private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            if (e.Exception != null)
            {
               //do somethine
            }
            if (e.Exception.InnerException != null)
            {
                //do logging?
            }
            //do logging?
        }
    
        // Catch-all exception handler
        private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject != null)
            {
                if (e.ExceptionObject is Exception)
                {
                    //do logging?
                }
            }
    
            //do logging?
        }
    

    【讨论】:

      【解决方案3】:

      没有办法做到这一点,而且尝试这样做是不明智的。如果发生未处理的Exception,您不知道发生了什么或为什么......在那之后漫无目的地继续不是一个好主意,因为您的应用程序可能没有互联网或数据库连接,或者任何其他会呈现的问题应用程序无法使用。

      更好的解决方案是处理您认为最有可能发生Exception 的所有情况,然后简单地记录(或存储在数据库中)任何确实发生并被捕获的Exceptions在AppDomain.UnhandledException 处理程序中。

      一旦Exception 到达该处理程序,避免关闭就为时已晚,但如果您记录到达该点的Exceptions,那么您可以查看发生了什么问题并添加进一步Exception 处理以解决这些问题。

      【讨论】:

      • “在那之后漫无目的地继续” 虽然是一个很好的一般规则,但 OP 并不是在谈论让应用程序继续,而不是让它自行重启有限数量的次。这是一个合法的用例 - 想想 Windows 服务 中的 Recovery 选项卡
      【解决方案4】:

      如果您希望应用程序在未处理的崩溃后重新启动,例如,如果它在 Kiosk 或类似设备上运行,您可能希望将其包装在一个简单的 shell 中。

      这个 shell 可以启动你的应用程序,在应用程序结束时检查返回值,并在它看起来崩溃时重新启动它。您可以计算崩溃次数并在多次后停止重新启动应用程序。当然可以使用AppDomain.UnhandledExceptionHandler 来创建未处理错误的日志,以便您修复这些错误并将代码包装在try .. catch 中。

      例如:

      // Start the application and wait for it to exit.
      var process = Process.Start(applicationPath, commandLineArguments);
      
      process.WaitForExit();
      
      // If the exit code is not 0, the application closed abnormally.
      if (process.ExitCode != 0)
      {
           // restart process   
      }
      

      如果您使用此技术,请不要忘记disable error reporting,这样重启过程不会被弹出对话框中断

      【讨论】:

        猜你喜欢
        • 2011-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-04
        • 1970-01-01
        • 2011-03-20
        • 1970-01-01
        • 2014-11-29
        相关资源
        最近更新 更多