在我看来,在从多个线程登录到文件时,我有一些类似于争用条件的东西。
1)我有一个自定义记录器类(ConfigurableTraceLogger),它由我的应用程序中的多个线程共享。它有大量的包装器函数,它们都调用主核心函数
protected void TraceData(String category, TraceEventType type, EventId id, string prefix, string format)
{
foreach (TraceListener item in _listeners)
{
IConfigurableTraceListener cl = item as IConfigurableTraceListener;
if (cl != null && cl.Category == category.ToLower())
{
if (DisplayMethodName)
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);
else
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, format);
item.Flush();
}
}
}如您所见,我的类只是在集合_listeners中存储不同的TraceListner类。基本上只有控制台和文本文件侦听器。TraceData做什么?它使用类别名称(即日志记录启动)并找到正确的侦听器。所有侦听器都由配置文件名定义。
现在,我的集合中还有我的自定义侦听器。
public class ConfigurableTextWriterTraceListener : TextWriterTraceListener, IConfigurableTraceListener该自定义类只覆盖一个属性。
protected override string[] GetSupportedAttributes()
{
return new string[] { "category" };
}当我在5到10分钟后启动我的应用程序时,我会在电话中出现异常。
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);例外情况是:
“复制内存时检测到可能的I/O争用条件。默认情况下,I/O包不是线程安全的。在多线程应用程序中,必须以线程安全的方式访问流,例如TextReader或TextWriter的同步方法返回的线程安全包装器。这也适用于StreamWriter和StreamReader等类。”
之后,我在同一次调用中多次得到第二个异常。
item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);异常
计数不能少于零。参数名称: count跟踪:“at System.String.CopyTo(Int32 sourceIndex,Char[]目的,Int32 destinationIndex,Int32 count)\r\n at System.IO.StreamWriter.Write(String value)\r\n at Int32 message)\r\n at System.Diagnostics.TraceListener.WriteHeader(String源,TraceEventType eventType,Int32 id)\r\n at System.Diagnostics.TraceListener.TraceData(TraceEventCache eventCache,String source,TraceEventType eventType,Int32 id,\r\n位于Jfc.Configuration.ConfigurableTraceLogger.TraceData(String类别、TraceEventType类型、EventId id、字符串前缀、字符串格式、Object[] args)“
在我看来,我的类对TraceData的调用也不是线程安全的。但据说ConfigurableTextWriterTraceListener线程毕竟是安全的。但是,我在运行时检查了IsThreadSafe的TextWriterTraceListener派生类,它是假的。我想找出问题出在哪里。
发布于 2009-11-09 16:16:49
这意味着-您的TraceListener不是线程安全的,当从几个线程访问时会中断。您需要使侦听器线程安全,或者找到确保只有一个线程访问任何特定实例的方法。
使它们线程安全的一种方法是使用同步队列,并使所有调用将数据项排队到队列中,而“真实”traceListener则将它们排到队列中,并将它们写入单独的线程中。
您还必须小心使用侦听器字典--更新字典并不是线程安全的,但是如果在应用上一次更新之前从未访问过它,则可以将其保留为
https://stackoverflow.com/questions/1701821
复制相似问题