我正在创建一个测试记录器,其中包含有关抛出的任何异常的信息,以便使用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。以上问题是否有效?
Q2。异常对象通常会引用很多其他数据吗?
答案 0 :(得分:4)
您的疑虑是有效的:异常对象可能会保留在任意其他对象上。这在实践中非常罕见。实际上我从未见过使用Exception.Data
属性。但我看到Exception
派生类使用自定义字段保留了大量内容:WebException
具有WebResponse
属性!
所以你看到即使像非托管资源这样昂贵的东西,你也可能活着。
我实际上会复制这些信息并丢弃Exception
。请务必复制InnerException
。
另一个问题可能是Exception
是可变类型。你可以在任何时候改变它的堆栈跟踪。因为这个原因,我想抓住它的状态。
内存使用也很重要。异常有一些可能从未使用过的字段。你可以保存它们。此外,将其字段内联到您的日志消息对象将消除对象标头和对象引用。虽然经常例外,但收益微不足道,但也许值得一试。
答案 1 :(得分:3)
坚持例外是可以的。
一般来说,他们没有太多数据(堆栈跟踪,错误消息和相关数据),但这并不是很多。
异常的一个实例不会影响同一类型的其他实例。
所以:
长时间坚持异常对象。
没问题。
如果异常对象阻止大对象被垃圾回收,则使用大量内存。
如果您向异常添加大量数据,则只会出现问题 - 如果不这样做,则不是问题。
在脱离上下文访问时返回错误值的异常。
不确定这意味着什么 - 背景是什么?例外是一个例外。
答案 2 :(得分:0)
我认为你应该意识到,当你写“长时间”或“很多”时,这些是相对的而不是绝对的,所以没有人能够说出这些问题是否过多。我的10核机器上有2Gb的RAM,而且我部署到Windows服务器,所以内存的影响不会让我感到烦恼。也许你在旧的Windows手机上运行,只有几个字节的备用RAM。谁知道?如果您有疑问,请记录您的记忆使用情况,但如果记忆存在问题,我会感到惊讶。
一般来说,对我来说更大的担忧是你可能会想要使用Exceptions作为向用户显示状态消息的方式,这并不酷。例外情况适用于特殊条件。你甚至可能无法有意义地恢复它们,更不用说像往常一样继续。如果要保留记录,可以将异常记录到数据库中(例如使用log4net),但我认为您最好记录它们而不是保留它们。