c#“缓存调试日志”
本文关键字:日志 调试 缓存 | 更新日期: 2023-09-27 18:04:14
我想向这里的c#专家寻求建议。我的调试日志有问题。我有一个简单的类,它只是打开一个文件,写入提供的字符串,并再次关闭文件。然而,有时我需要使用这个调试日志,而我正在使用多线程。于是麻烦来了。我不能让文件打开多次,所以我收到一个异常,因为我只是试图再次打开被锁定的文件。出于这个目的,我希望有一个类似于"缓存调试日志"的东西,它可以防止这种异常。有没有什么简单的方法来实现这一点?
c# 4.0提供了像System.Collections.Concurrent.ConcurrentQueue<T>
这样的线程安全集合。您可以修改日志记录类,使其在自己的线程中运行,并且调用日志方法只是将消息添加到这样的队列中。这样,日志线程就可以安全地从队列中读取条目,并写入文件,而不会中断。
编辑
当然,最方便的做法是开始使用预先存在的日志框架,该框架已经处理好了这些事情。我推荐NLog,尽管log4net也是一个有价值的竞争者。
这通常是通过在代码的所有部分调用一个单例记录器来完成的;日志记录器是唯一直接访问文件的东西。现在已经有很多框架(nlog、log4net、enterprise library)可以为您完成这些工作。
您可能想要查看。net Tracing。我更喜欢使用内置的TraceSource类,而不是使用第三方日志框架(如nlog)。我以前甚至会围绕nlog编写一个facade,但是有这么多依赖关系和这么多抽象层,只是为了写一条日志消息,这似乎相当愚蠢。
您可以在这里看到TraceSource的概述:http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource.aspx
这个想法是你把跟踪从监听中分离出来。在整个代码中,您可以添加跟踪调用,每个调用具有不同的日志级别(Error、Verbose、Debug)和不同的源。然后在应用程序配置中配置不同的侦听器。
<system.diagnostics>
<sources>
<source name="Source1" switchName="verboseSwitch">
<listeners>
<add name="console" />
</listeners>
</source>
<source name="Source2" switchName="warningSwitch">
<listeners>
<add name="console" />
</listeners>
</source>
</sources>
<switches>
<add name="verboseSwitch" value="Verbose" />
<add name="warningSwitch" value="Information" />
</switches>
<sharedListeners>
<add name="console" type="System.Diagnostics.ConsoleTraceListener" initializeData="false"/>
</sharedListeners>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="console" />
</listeners>
</trace>
</system.diagnostics>
public void MethodOne()
{
TraceSource ts = new TraceSource("Source1");
ts.TraceEvent(TraceEventType.Verbose, 0, "Called MethodOne");
// do something that causes an error
ts.TraceEvent(TraceEventType.Error, 0, "MethodOne threw an error");
}
在这里,MethodOne被设置为使用源"Source1"。Source1目前在上面配置为侦听任何Verbose和更高级别的内容。这意味着
Called MethodOne
MethodOne threw an error
将同时写入控制台
public void MethodTwo()
{
TraceSource ts = new TraceSource("Source2");
ts.TraceEvent(TraceEventType.Verbose, 0, "Called MethodTwo");
// do something that causes a error
ts.TraceEvent(TraceEventType.Error, 0, "MethodTwo threw an error");
}
在这里,MethodTwo被配置为使用Source2,它只被设置为侦听Warning及以上。
因此,当代码运行时,输出将是MethodTwo threw an error
允许你做的是控制你希望在程序的不同部分看到多少信息。也许,如果有一天您开始在某些库中看到错误,您可以将该库的跟踪源设置为verbose,现在可以看到所有调试信息,而不会被程序其他部分的数据所淹没。
我使用不同的侦听器来控制关键错误的流程。我有针对特定来源和特定错误级别的监听器,一旦有错误写入日志,它们就会给我发电子邮件。我不关心404错误,但我确实关心注册码中发生的任何事情,例如。
您有用于写入控制台/调试窗口的ConsoleTraceListenerFileLogTraceListener用于写入文件甚至EventLogTraceListener
您可以在这里看到内置侦听器的完整列表
然后是第三方侦听器,用于发送日志事件的电子邮件,存储在数据库中,写入Azure表存储等。
你当然可以用NLog这样的框架来完成所有这些。. net Trace方法是高性能的,并且在。net框架中广泛使用。我觉得你选它不会错的。