从控制台程序登录到txt文件的有效方法

时间:2020-03-06 14:55:45  来源:igfitidea点击:

从Cand .NET 2.2上的控制台程序向日志(.txt)记录的最有效方法是什么?我的程序多次循环执行,总是根据用户的需求输出不同的数据,因此我正在寻找实现这一目标的最有效方法。

我知道我总是可以重新打开一个流,然后关闭它,但是每次这样做,它只会写一行,然后在下一次(几秒钟后)再次循环并需要再次写。在我看来,这似乎并不十分节省资源。

我正在使用多个线程,这些线程都具有要记录的输出数据(在不同线程上打开/关闭同一文件或者访问同一文件可能是不好的)。 "持有对自动刷新的流编写器的引用"听起来是个好主意,但是我不知道该怎么做。

解决方案

考虑使用log4net:

a tool to help the programmer output log statements to a variety of output targets... We have kept the framework similar in spirit to the original log4j while taking advantage of new features in the .NET runtime. For more information on log4net see the features document...

我接受每次写行时打开和关闭所带来的性能损失。这是可靠性的决定。如果将所有内容都保留在内存中,并且发生严重崩溃,则根本没有日志信息可进行故障排除。如果我们不关心此问题,那么将其保存在内存中肯定会提供更好的性能。

一种简单的方法是提供一个TextWriterTraceListener并将其添加到Trace类的TraceListeners集合中。这将自动将所有Trace.Write ...调用写入相应的文件。

我同意使用log4net。

但是,如果我们真的需要简单的东西,请考虑仅拥有一个对StreamWriter的引用的单例,该引用会在每个WriteLine上自动刷新。

因此,我们可以在整个会话期间保持文件处于打开状态,从而避免关闭/打开的开销,同时避免在发生严重崩溃的情况下冒着丢失日志数据的风险。

我们可以加入构成CLR一部分的跟踪框架。使用简单的类,例如:http://www.chaosink.co.uk/files/tracing.zip,我们可以有选择地记录诊断信息。要使用它,请将类添加到应用程序。在班级中创建示踪剂的外观,例如:

private Tracing trace = new Tracing("My.Namespace.Class");

并使用以下命令调用它:

MyClass()
{
    trace.Verbose("Entered MyClass");
    int x = 12;
    trace.Information("X is: {0}", x);
    trace.Verbose("Leaving MyClass");
}

内置的跟踪框架中共有4级信息:

详细记录程序流程

信息记录监控人员感兴趣的特定信息

警告记录无效状态或者可恢复的异常

错误记录不可恢复的异常或者状态

要从应用程序访问信息,然后将以下内容添加到app.config(或者web.config)中:

<system.diagnostics>
    <trace autoflush="false" indentsize="4">
        <listeners>
            <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\mylogfile.log" />
        </listeners>
    </trace>
    <switches>
        <add name="My.Namespace.Class" value="4"/>      
    </switches>
</system.diagnostics>

我们还可以将用于发布的侦听器添加到事件日志或者我们感兴趣的其他任何位置。有关跟踪框架的更多信息,请参见:

http://msdn.microsoft.com/en-us/library/ms733025.aspx

诸如log4net之类的日志记录框架应正确处理多线程。

可能还会有一个有用的提示:日志记录会严重污染代码,使代码的可读性降低。我们是否考虑过在编译时使用Aspect向代码注入日志记录功能?有关示例,请参见本文。