我想在这里向C#专家征求意见。我的调试日志有问题。我有一个简单的类,只打开一个文件,写下提供的字符串并再次关闭文件。但是,有时我需要在使用多线程时使用此调试日志。从而麻烦来了。我不能多次打开文件,所以我收到异常,因为我只是尝试再次打开锁定的文件。为此,我希望有一个类似“缓存的调试日志”的东西,它可以防止这种异常。有没有简单的方法来实现这个?非常感谢。
答案 0 :(得分:2)
C#4.0提供了类似System.Collections.Concurrent.ConcurrentQueue<T>
的线程安全集合。您可以修改日志记录类,使其在自己的线程中运行,并且对日志方法的调用只是将消息添加到此类队列中。这样,您的日志记录线程就可以安全地从队列中读取项目,并不间断地写入文件。
修改强>
当然,最有利的做法是开始使用已经存在这些东西的预先存在的日志框架。我推荐NLog,虽然log4net也是一个有价值的竞争者。
答案 1 :(得分:1)
这通常是通过从代码的所有部分调用的单例记录器来完成的;记录器是唯一直接访问文件的东西。有许多框架已经存在(nlog,log4net,企业库),可以为您完成此任务。
答案 2 :(得分:1)
您可能想要查看.NET跟踪。我更喜欢使用内置的TraceSource类和使用像nlog这样的第三方日志框架。我曾经走过甚至围绕nlog写一个立面的道路,但是那么拥有如此多的依赖关系和如此多的抽象层似乎相当愚蠢,只是为了写一条日志消息。
您可以在此处查看TraceSource的概述:http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource.aspx
这个想法是你将追踪与听力区分开来。在整个代码中,您可以添加跟踪调用,每个调用具有不同的日志级别(错误,详细,调试)和不同的源。在应用程序配置中,然后配置不同的侦听器。
<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目前在上面配置为侦听任何详细和更高版本。所以这意味着
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,它仅设置为侦听警告及以上。
因此,当代码运行时,输出将是
MethodTwo threw an error
这使您可以控制您希望在程序的不同部分看到多少信息。也许如果有一天你开始在某个库中看到错误,你可以将该库的跟踪源变为详细,现在可以查看所有调试信息,而不会被来自程序其他部分的数据所淹没。
我使用这样的不同监听器来控制关键错误的流动。我有一些侦听器用于某些来源和某些错误级别,这些错误级别会在错误写入日志时向我发送电子邮件。我不关心404错误,但我确实关心注册代码中发生的任何事情,例如。
您有ConsoleTraceListener用于写入控制台/调试窗口 用于写入文件的FileLogTraceListener 甚至是EventLogTraceListener
您可以查看内置侦听器的完整列表here
然后有第三方侦听器用于发送日志事件的电子邮件,存储在数据库中,写入Azure表存储等等。
您当然可以使用像NLog这样的框架来完成所有这些工作。 .NET Trace方法具有高性能,可在整个.NET Framework中使用。你选择它不会出错恕我直言。