2013-02-07 132 views
3

我正在创建一个测试记录器,其中将包含有关引发的任何异常的信息,以便可以使用GUI正确显示它们。坚持异常对象是否安全?

是否可以安全使用下面的结构:

public class TestLogEntry { 
    public System.Exception Exception { get; private set; } 

    public TestLogEntry(/*...,*/ System.Exception exception = null) { 
     //... 

     Exception = exception; 
    } 
} 

或者将以下比较好?

public class TestLogEntry { 
    public string StackTrace { get; private set; } 
    public System.Type ExceptionType { get; private set; } 
    public string ExceptionMessage { get; private set; } 

    public TestLogEntry(/*...,*/ System.Exception exception = null) { 
     //... 

     if (exception != null) { 
      StackTrace = exception.StackTrace; 
      ExceptionType = exception.GetType(); 
      ExceptionMessage = exception.Message; 
     } 
    } 
} 

虽然第一种方法是更灵活(因为它可以包含其他自定义数据),这里有我的顾虑:

  • 永保异常对象后长时间。
  • 如果异常对象阻止大对象被垃圾收集,则使用大量内存。
  • 异常在上下文访问时返回错误值。

Q1。上述问题是否有效? Q2302。异常对象通常会引用很多其他数据吗?

+0

通常,异常对象不会引用大量数据。在执行日志代码的持续时间内,您应该保持您的异常对象。 –

回答

4

您的关注是有效的:异常对象可能守住任意其他对象。这在实践中非常罕见。其实我从来没有见过使用Exception.Data属性。但是我看到派生类保留了一些使用自定义字段的东西:WebException有一个WebResponse属性!

所以你看,你可能会保持活着甚至一些昂贵作为非托管资源。

我实际上将信息复制并丢弃Exception。记得也要复制InnerException

不同的问题可能是Exception可变类型。您可以随时更改其堆栈跟踪。我想为了这个原因捕捉它的状态。

同样重要的是内存使用情况。例外有一些可能从未使用过的字段。你可以保存它们。另外,将它的字段内联到日志消息对象中将消除对象头和对象引用。一个小的收益,但可能值得采取的情况下,经常例外。

+0

关于WebResponse,响应流可能不会有效。所以应该考虑到这一点。 –

+1

这也是捕捉内部异常的一个好处。 –

3

坚持例外是好的。

一般来说,他们并不抱多大的数据(堆栈跟踪,错误信息和相关数据),但是这也不是很多。

而且异常的一个实例不会影响即使是同一类型的其他实例。

所以:

永保异常对象后长时间。

没有问题。

如果异常对象阻止大对象被垃圾收集,则使用大量内存。

如果您将大量数据添加到您的例外中,那么这只是一个问题 - 如果您不这样做,那不是问题。

异常时断章取义的访问返回错误的值。

不知道这意味着什么 - 什么情况下?例外是一个例外。

+0

>异常在上下文访问时返回错误的值。 如果异常封装某个对象并返回基于该对象的值,则在稍后阶段更改所述对象的状态,以使异常信息不正确。 –

+0

@LeaHayes这是可能的,但我认为这不是最佳做法。 –

0

我认为你应该认识到,当你写“长时间”或“很多”这些是相对而不是绝对的术语,所以没有人能够说这些问题是否太多。我的10核机器上有2Gb的内存,并且我部署到了Windows服务器上,所以内存的影响丝毫不会影响到我。也许你正在使用只有几个字节的备用RAM的旧Windows电话上运行。谁知道?如果您有疑问,请分析您的记忆使用情况,但如果记忆存在问题,我会感到惊讶。

一般来说,对我来说更大的担忧是您可能会尝试使用例外作为向用户显示状态消息的方式,这并不酷。例外情况是例外条件。你甚至不能有意义地从它们中恢复过来,更不用说像往常一样继续。例外情况可以记录到数据库(如使用log4net),如果你想记录它们,但我认为你会更好地记录它们而不是保留它们。

+0

异常消息和堆栈跟踪与我的目标受众(他们自己是程序员)相关,但我确实理解您的建议。 –

+0

内存明智我担心内置于.NET或我们正在使用的库的异常可能会在内存中引用可能非常大的对象,从而使它们“活着”。 –