我从记录到文件时看起来像是竞争条件 多线程。
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();
}
}
}
正如您所看到的,我的类只是在集合中存储了不同的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包不是线程安全的。在多线程应用程序中,必须以线程安全的方式访问流,例如线程-safe包装器由TextReader或TextWriter的Synchronized方法返回。这也适用于StreamWriter和StreamReader等类。“
之后,我在同一次
的同一次呼叫中多次遭遇第二次异常item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);
异常
计数不能小于零。 参数名称:count 堆栈跟踪:“System.String.CopyTo(Int32 sourceIndex,Char [] destination,Int32 destinationIndex,Int32 count)\ r \ n在System.IO.StreamWriter.Write(String value)\ r \ n在System.Diagnostics中。 System.Diagnostics.TraceListener.WriteHeader中的TextWriterTraceListener.Write(String message)\ r \ n \ n(系统.Diagnostics.TraceListener.TraceData中的字符串源,TraceEventType eventType,Int32 id)\ r \ n(TraceEventCache eventCache,String source,TraceEventType eventType ,Int32 id,Object data)\ r \ n at Jfc.Configuration.ConfigurableTraceLogger.TraceData(String category,TraceEventType type,EventId id,String prefix,String format,Object [] args)“
在我看来,我的类不是线程安全的,也不是对TraceData的调用。但是ConfigurableTextWriterTraceListener毕竟是线程安全的。但是我在运行时检查了我的TextWriterTraceListener派生类的IsThreadSafe propety 这是假的。我试图找出问题所在。
答案 0 :(得分:1)
这意味着什么 - 您的TraceListener不是线程安全的,并且在从多个线程访问时会中断。您需要使侦听器线程安全或找到确保只有一个线程访问任何特定实例的方法。
使它们成为线程安全的一种方法是使用同步队列并使所有调用将数据项排入队列,而'real'traceListener将它们出列并将它们写在一个单独的线程中。
你还必须小心你的听众字典 - 更新字典不是线程安全的,但如果你在上次更新之前从未访问它,你可以保持原样