【问题标题】:Catching all exception捕捉所有异常
【发布时间】:2013-03-05 23:14:19
【问题描述】:

我有一个项目可能会在任何函数和对象上抛出异常,有没有办法在整个框架/程序中捕获任何和所有异常,以便我可以记录它们以便以后可以看到它们?我想要调用堆栈和异常消息。我不一定知道异常将在哪里抛出,但我想记录在程序整个生命周期中任何地方发生的任何异常。有没有办法做到这一点?我不想尝试捕捉任何可能的异常抛出函数。程序会因为未处理的异常而中断,但我想先记录它。

【问题讨论】:

  • 这是网页、win 表单还是其他类型的项目?
  • Windows 桌面应用,特别是 WCF。
  • 你的意思是它是一个 WCF 服务,在 Windows 窗体应用程序中自托管?

标签: c# wcf exception-handling


【解决方案1】:

是的,有办法做到这一点。 在正文中写下以下几行:

// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new ThreadExceptionEventHandler(MainForm_UIThreadException);

// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

// Add the event handler for handling non-UI thread exceptions to the event. 
AppDomain.CurrentDomain.UnhandledException +=
    new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

然后处理异常

private static void MainForm_UIThreadException(object sender, ThreadExceptionEventArgs t)
{
    //do something
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    //do something
}

【讨论】:

    【解决方案2】:

    捕获异常的一个要点是根据抛出的异常类型正确处理它们。通过拥有一个大型异常处理程序,您将无法处理单个异常,而可能只是吞下它们。但这并不是说在所有情况下都不能或不应该这样做。

    如果您的项目需要一个大型处理程序,那么您可以简单地处理AppDomain.UnhandledException 事件。即使您在其他地方捕获异常,处理此方法也是一个好主意,以确保您的程序不会在您错过异常时抛出不友好的错误。这假设您正在创建一个WinForm

    由于您也在使用WCF,您可以查看IErrorHandler 接口来帮助处理故障消息。

    【讨论】:

      【解决方案3】:

      有没有办法在整个框架/程序中捕获任何和所有异常,以便我可以记录它们以便以后可以看到它们?

      捕获所有应用程序类型的所有未处理异常的唯一方法是使用已经提到的AppDomain.CurrentDomain.UnhandledException。但是,您不能阻止您的应用程序使用该事件终止(好吧,您可以,但我不会告诉您如何,因为它有点骇人听闻)。

      然而,在大多数框架中都有一些方法可以捕获未处理的异常,这些方法允许您锁定异常并继续前进。既然您提到了 WCF,您可能想了解一下 IErrorHandler

      我不想尝试捕获任何可能的异常抛出函数。

      我就是这样做的。 Do NOT catch that exception。 ;)

      【讨论】:

        【解决方案4】:

        您可以在应用域级别捕获异常 -App Domain Exception

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

        如果您阅读链接,它提到一些其他事件可能会导致应用程序域不触发 - 例如 ThreadException - 因此可能需要多个处理程序。

        Application.ThreadException += new ThreadExceptionEventHandler (ThreadExceptionHandler);
        

        还要注意以下几点:(与 winforms 相关 - SetUnhandledExceptionMode

        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        

        【讨论】:

        • Application 仅适用于 winforms。你可能想提一下。
        【解决方案5】:

        你总是可以使用AppDomain.UnhandledException

        static void Main()
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            currentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomain_UnhandledException);
        }
        
        private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs args) {
            Logger.Log((Exception)args.ExceptionObject);
        }
        

        【讨论】:

          【解决方案6】:

          有没有办法在整个过程中捕获任何和所有异常 框架/程序,以便我可以记录它们以便我以后可以看到它们?

          是的,桌面应用程序或 Web 应用程序有处理程序来处理未处理的异常。在桌面应用程序中,该事件称为 UnhandledException。在 Web 应用程序中,它是应用程序入口点上的 Application_Error(通常是 Global.asax.cs)。

          我不想尝试并捕捉任何可能的异常抛出 功能。程序会因为未处理的异常而中断,但我 想先记录下来。

          如果您不想捕获异常,您总是可以简单地重新抛出。它将继续冒泡以使程序崩溃。

          catch(Exception ex)
          {
              //logging here
              throw;//rethrow
          }
          

          我想要调用堆栈和异常消息。

          Exception 类包含这些。在事件处理程序的情况下,有多种访问方式取决于它是什么类型的应用程序。

          【讨论】:

            猜你喜欢
            • 2012-01-10
            • 1970-01-01
            • 2020-04-20
            • 1970-01-01
            • 1970-01-01
            • 2023-04-04
            • 2018-01-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多