【问题标题】:how to include the actual form classname in logging from FirstChanceException?如何在 FirstChanceException 的日志记录中包含实际的表单类名?
【发布时间】:2019-05-14 12:31:12
【问题描述】:

我的情况如下:

  • 我有一个表格FormBase
  • 从此FormBaseListFormBaseDetail 继承

现在在我的主窗体上,我想从 FirstChanceException 事件中记录一些异常。我记录了Exception.Message 和完整的stacktrace

但是在stacktrace我有问题。
例如,我创建了一个表单 FormCustomerDetail 及其派生自 FormBaseDetail
并且在FormBaseDetail 中定义的受保护或私有方法中发生异常,则堆栈跟踪将显示FormBaseDetail 而不是FormCustomerDetail
这对我来说是个问题,因为现在我不知道异常发生的实际形式。从FormBaseDetail派生出来的表格大概有50种

所以问题是,FirstChanceException 事件中有没有办法检索实际表单的类名?还是名字?

AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;

private void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
    StackTrace stackTraceObject = new StackTrace();
    string stackTrace = stackTraceObject.ToString();

    // I need to retrieve the actual form name or classname here...
    LogError(
      //ActualFormName + Environment.NewLine +  
      e.Exception.GetType().FullName + Environment.NewLine +  
      e.Exception.Message + Environment.NewLine + 
      stackTrace);
}

日志条目示例:

System.FormatException
Cannot convert xx to type boolean...
...
at Test_app.FormBaseDetail.OpenTables()  
at Test_app.FormBaseDetail.PrepareFormLoad()
...

我想得到什么

Exeption occured in FormCustomerDetail
System.FormatException
Cannot convert xx to type boolean...
...
at Test_app.FormBaseDetail.OpenTables()  
at Test_app.FormBaseDetail.PrepareFormLoad()
...

【问题讨论】:

  • 您正在寻找一种方法来在发生异常时解析堆栈上的局部变量实例。不幸的是,StackTrace 类似乎不支持这一点。调试器可以,但这在这里可能没有帮助。 -- 顺便说一句,这是第一次机会,而不是第一次改变。

标签: c# .net winforms exception-handling stack-trace


【解决方案1】:

天真的方法是将其实际记录在基本表单中 - 即有类似的东西:

class FormBaseDetail 
{
   private void Guard(Action a)
   {
       try { a.Invoke(); }
       catch(Exception e)
       {
          throw new Exception("Exception on '" + this.GetType() + "'", e);
       }
   }

   // pretty much everywhere in base class
   public void PrepareFormLoad() 
   {
      Guard(() => { ... });
   }
}

此外,我可以想象挂钩 FormLoad 并将 Form 的活动类型放入某个静态变量中。

【讨论】:

  • 是的,但这只有在我把它放在每种形式的每种方法中都有效,对吧?
  • @GuidoG - 只是基本表单(FormBaseDetail - 如果在子表单方法(比如 FormCustomerDetail)中发生异常,您应该能够从堆栈跟踪中推断出类型。但是是的 - 您必须将其放入所有 FormBaseDetail 方法中。
  • 好的,但是调用会对性能或消息队列有任何影响吗?
  • 每个 try 块都会有非常非常小的性能损失;但在 UI 操作上我不介意。参考stackoverflow.com/questions/1308432/…
  • 好吧,我想我可以试试这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 2017-03-15
  • 2021-05-12
  • 2016-08-11
  • 2023-03-11
相关资源
最近更新 更多