3

我正在滚动我自己的记录器类,并希望在应用程序经历不同阶段时表示日志的层次结构:

log start
    loading
        loaded 400 values
    processing
         couldn't process var "x"

等等

在 C++ 中(是的,我知道),我会使用 RAII 类,它们在创建时将自身推入日志堆栈,并在它们离开范围时弹出。然后,您可以在任何时候离开函数,并且仍然具有一致的日志记录。

显然,在 C# 中,任何变量都必须是新的,因此在下一个垃圾回收周期之前它不会被删除,如果您立即创建一个新的 classlet,您可能会有一个不同步的记录器。

人们将如何尝试在 C# 中解决这个问题?我希望记录器语法对当前函数尽可能不显眼,并且仍然支持具有多个退出点的函数。

我能想到的唯一解决方案是 closeHeirarchy() 调用每个 return 语句 - 你知道我会在某个地方错过一个。


编辑:我应该明确表示我主要对如何在 c# 中复制 RAII 行为感兴趣。是否有提供相同行为的机制?

4

3 回答 3

5

如果您将using语句与 IDisposable 类一起使用,您可以获得您所询问的行为。

做这样的事情:

public class LogContext: IDisposable
{
  private readonly Logger _logger;
  private readonly string _context;

  public LogContext(Logger logger, string context){
    _logger = logger;
    _context = context;
    _logger.EnterContext(_context);
  }

  public void Dispose(){
    _logger.LeaveContext(_context);
  }
}

//...

public void Load(){
  using(new LogContext(logger, "Loading")){
    // perform load
  }
}
于 2009-01-23T18:22:15.057 回答
3

OffTopic:如果您希望“记录器语法对客户端代码尽可能不显眼”,您可能希望在记录器完成后查看面向方面的编程。但也许您应该采取一条不那么痛苦的路线,并使用任何可用的出色记录器(log4Net、NLog、System.Trace 甚至 Spring.Commonlogging)。

于 2009-01-23T18:08:16.300 回答
1

System.Diagnostics.Trace值得一看。例如,它支持缩进级别。log4net项目也值得一试。

于 2009-01-23T18:00:57.110 回答