2011-08-03 71 views
1

我想问问C#专家在这里寻求建议。我的调试日志有问题。我有一个简单的类,只是打开一个文件,写下提供的字符串并再次关闭文件。但是,有时我需要在使用多线程时使用此调试日志。从而麻烦来了。我无法打开多个文件,因此我收到一个异常,因为我只是试图再次打开锁定的文件。为了这个目的,我希望有一些像“缓存调试日志”这样可以防止这种异常。有没有简单的方法来实现这一点?提前致谢。C#“缓存调试日志”

回答

2

C#4.0提供线程安全集合,如System.Collections.Concurrent.ConcurrentQueue<T>。你可以修改你的日志记录类,使它在自己的线程中运行,并且调用日志方法只需将消息添加到这样的队列中。这样,您的日志记录线程就可以安全地读取队列中的项目,并且不中断地写入文件。

编辑

当然,最方便的事情是开始使用已经有这个东西的照顾预先存在的日志框架。我推荐NLog,尽管log4net也是一个有价值的竞争者。

+0

+1为NLog,我认为它比log4net好。 – kprobst

1

这通常是通过从代码的所有部分调用单例记录器完成的;记录器是直接访问文件的唯一东西。有许多已经存在的框架(nlog,log4net,企业库)可以为您做到这一点。

+0

感谢您的回答,我的项目不是很复杂,所以我认为使用类似NLog的东西就像使用机枪杀死一只苍蝇:)。 – Danstahr

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 

会虽然MethodTwo配置为使用源2,这是只设置了听警告及以上的都被写入到控制台

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 threw an error 

这是什么让你做的是控制你要多少信息,看看你的程序的不同部分。也许如果有一天你开始在某个库中看到错误,你可以将该库的跟踪源变成冗长的,现在看到你所有的调试信息,而不会被程序其他部分的数据淹没。

我使用不同的监听器来控制关键错误的流程。我有听众的某些来源和某些错误级别,这些错误会在错误写入日志时给我发电子邮件。例如,我不在乎404错误,但我关心注册码中发生的任何事情。

你有ConsoleTraceListener写入到控制台/调试窗口 的FileLogTraceListener用于写入文件 即使EventLogTraceListener

你可以看到内置的听众here

然后有三分之一的完整列表第三方听众发送关于日志事件的电子邮件,存储在数据库中,写入Azure表存储等。

你当然可以用类似框架来完成所有这些NLOG。 .NET跟踪方法具有很高的性能,可以在.NET Framework中使用。选择它恕我直言,你不会出错。