【问题标题】:C#: Can I get the details from an Unhandled Exception from the CLR?C#:我可以从 CLR 的未处理异常中获取详细信息吗?
【发布时间】:2011-01-04 06:23:02
【问题描述】:

首先,很抱歉必须是重复的帖子。我似乎无法在 SO 和 google 上缩小搜索范围以找到我正在寻找的内容。

我目前在一家商店工作,他们喜欢让他们的例外冒泡。当编译的应用程序进行测试时,试图获取异常的详细信息(消息和堆栈跟踪)是一件非常痛苦的事情。 Windows 显示了那个熟悉的框,它从来没有任何细节。

在最近花了近一个小时发现测试盒的水晶报告版本错误后,我添加了这个大家可能都熟悉的简单代码。

    static void Main(string[] arg)
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run( ... );
    }

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.ToString());
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).ToString());
    }

这可以完成工作,但我不允许签入。是否有任何方法可以在 app.config 中或通过注册表设置让 CLR 显示或记录已编译的 .net 应用程序的异常详细信息?

提前感谢您的帮助。

【问题讨论】:

  • 你不能用日志替换你的 MessageBox 调用,然后重新抛出异常吗?
  • 您是否考虑过插入日志记录 DLL(如 log4net)或 EnterpriseLibrary 日志记录,然后按照 Martin 的建议进行操作?

标签: c# .net exception-handling clr


【解决方案1】:

我正在使用 WPF,所以这里是所有未处理的异常冒泡的地方,它可能对您的需求有用:

Private Sub Application_DispatcherUnhandledException(ByVal sender As Object, ByVal e As System.Windows.Threading.DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
    'TODO: Log error'

    Dim sb As New System.Text.StringBuilder(e.Exception.Message & vbCrLf)

    Dim ex = e.Exception.InnerException
    While ex IsNot Nothing
        sb.AppendLine("______________ inner exception: ______________")
        sb.AppendLine(ex.Message)
        sb.AppendLine(vbCrLf)
        ex = ex.InnerException
    End While

    If MessageBox.Show(sb.ToString, "Exception caught", MessageBoxButton.OKCancel) = MessageBoxResult.Cancel Then Stop
    e.Handled = True
End Sub

接受我的道歉,我没有时间重写它,我只是复制了我的原始代码,我相信它仍然有帮助。

谢谢

【讨论】:

    【解决方案2】:

    如果您想配置日志输出,只需使用log4net。

    【讨论】:

      【解决方案3】:

      如果您知道如何在 VB.NET 中编码,Shimmy 的解决方案会很方便。

      然后你可以递归到ex.InnerException.InnerException....等等...构造一个完整的消息

      (1) 如果ex.Message 不是null 或Empty,则显示它。

      (2) 如果ex.InnerException 不是null,则显示ex.InnerException.Message。

      【讨论】:

        【解决方案4】:

        您可以选择将调试处理代码包装在条件编译符号中。这将允许您提供所需的详细日志记录以用于测试目的,但在应用程序的发布版本中,最终用户无法使用。

        【讨论】:

          【解决方案5】:

          看起来您在 Main() 方法中缺少顶级 try-catch。示例见one of my answers。

          我不会使用MessageBox,而是使用一种静态方法以您想要/需要的方式记录问题,然后显示通用“发生意外致命错误。[Bla bla bla]”消息并杀死正在运行的进程就ok了。

          【讨论】:

            【解决方案6】:

            你能用Enterprise Library吗?有可能对您有用的异常处理和日志记录块。您可以将异常处理块配置为notify and rethrow 原始异常,并使用日志记录块记录详细信息。攀登和掌握它可能有点陡峭,但我认为最终还是值得的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-04-28
              • 2016-08-14
              • 1970-01-01
              相关资源
              最近更新 更多