基于XmlWriterTraceListener的线程安全跟踪侦听器

时间:2013-03-15 15:52:36

标签: .net thread-safety extend tracelistener

我想用一个监听器替换默认的Microsoft XmlTraceListener,该监听器根据文件大小限制或当前日期切换文件。我想保留默认的XmlTraceListener文件格式,以便我可以使用ServiceTraceViewer工具打开文件。

我发现了一篇文章http://www.codeproject.com/Articles/30956/A-Rolling-XmlWriterTraceListener,但是从评论来看,即使应用了建议的补丁,这个监听器似乎也有一些不稳定性。

然后我找到了Microsoft自己的CircularListener http://msdn.microsoft.com/en-us/library/aa395205.aspx

的实现

我想扩展它,但注意到它有

static CircularStream m_stream = null;

后来这个变量没有锁就被访问了。在阅读http://msdn.microsoft.com/en-us/library/ms733025.aspx时,我发现即使XmlWriterTraceListener本身也不是线程安全的。 MSDN说:

  

因为System.Diagnostics.XmlWriterTraceListener不是线程安全的,   跟踪源可以在输出时专门锁定资源   痕迹。当许多线程将跟踪输出到配置的跟踪源时   要使用此侦听器,可能会发生资源争用,从而导致   一个重要的性能问题。要解决此问题,您应该这样做   实现一个线程安全的自定义侦听器。

所以基本上这意味着TraceListener.IsThreadSafe属性保留为false用于XmlWriterTraceListener,因此每当调用TraceData / TraceEvent时,更高级别的跟踪系统都会锁定,我是对的吗?

围绕static CircularStream m_stream添加锁并从覆盖true属性返回IsThreadSafe会有什么好处吗?或者它可能与XmlTraceListener中已经完成的事情相同?

如何使CircularTraceListener线程安全且高效?

1 个答案:

答案 0 :(得分:1)

我认为CircularTraceListener基本上是有缺陷的。您已经注意到有static m_stream。但是,更糟糕的是,当您构造CircularTraceListener时,它会将新流传递到基础(XmlWriterTraceListener)。这意味着虽然CircularTraceListener只知道 last 创建的流,但基类可能使用许多流中的一个。当然,如果CircularTraceListener被释放,基类将处置共享的m_stream对象。

我建议你不要从CircularTraceListener开始做任何事情并从头开始。

更新

对于像循环日志这样的东西,我在运行log4net和NLog等方面运气好多了。