简体   繁体   English

竞争条件/ TextWriterTraceListener

[英]Race condition / TextWriterTraceListener

I have something wich looks to me like race condition while logging to file from multiple thread. 从多线程登录到文件时,我有一种看起来像竞争状况的东西。

1) I've got a custom logger class (ConfigurableTraceLogger) that is shared by multiple threads in my application. 1)我有一个自定义记录器类(ConfigurableTraceLogger),该类由应用程序中的多个线程共享。 It's has lots of wrapper functions which all call to main core function 它有很多包装函数,都调用了主核心函数

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();
        }
    }
}

As you can see my class simply stores different TraceListner-derved class in a collection _listeners. 如您所见,我的类只是在集合_listeners中存储了不同的TraceListner-derved类。 Basically there are only console and text file listeners. 基本上只有控制台和文本文件侦听器。 What TraceData does it takes the category name (ie logging start-up) and finds the right listener. TraceData会执行的操作使用类别名称(即启动日志记录)并找到正确的侦听器。 All listeners are defined by config file name 所有侦听器均由配置文件名定义

Now I also have my custom listeners in the collection 现在,我在集合中也有我的自定义监听器

public class ConfigurableTextWriterTraceListener : TextWriterTraceListener, IConfigurableTraceListener

That custom class overrides nothing except for one property. 该自定义类除一个属性外不覆盖任何内容。

protected override string[] GetSupportedAttributes()
{
    return new string[] { "category" };
}

When I start my application after 5 to 10 minutes I get exception on the call 5至10分钟后启动应用程序时,通话异常

           item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);

Exception is saying: 例外是在说:

"Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader." “复制内存时检测到可能的I / O竞争状态。默认情况下,I / O包不是线程安全的。在多线程应用程序中,必须以线程安全的方式访问流,例如TextReader的返回的线程安全包装器或TextWriter的Synchronized方法。这也适用于StreamWriter和StreamReader之类。”

After that I keep getting second exception lots of times on the same call to 在那之后,我在同一通电话上多次出现第二次异常

item.TraceData(new TraceEventCache(), _instanceName, type, (int)id, prefix + format);

Exception 例外

Count cannot be less than zero. 计数不能小于零。 Parameter name: count Stack trace: " at System.String.CopyTo(Int32 sourceIndex, Char[] destination, Int32 destinationIndex, Int32 count)\\r\\n at System.IO.StreamWriter.Write(String value)\\r\\n at System.Diagnostics.TextWriterTraceListener.Write(String message)\\r\\n at System.Diagnostics.TraceListener.WriteHeader(String source, TraceEventType eventType, Int32 id)\\r\\n at System.Diagnostics.TraceListener.TraceData(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)" 参数名称:count堆栈跟踪:“位于System.IO.StreamWriter.Write(字符串值)\\ r \\ n,位于System.String.CopyTo(Int32 sourceIndex,Char []目标,Int32 destinationIndex,Int32计数)\\ r \\ n System.Diagnostics.TraceListener.WriteHeader(System.Diagnostics.TraceListener.TraceData(TraceEventCache eventCache,String)上的System.Diagnostics.TextWriterTraceListener.Write(String message)\\ r \\ n(String source,TraceEventType eventType,Int32 id)\\ r \\ n源,TraceEventType eventType,Int32 id,对象数据)\\ r \\ n位于Jfc.Configuration.ConfigurableTraceLogger.TraceData(字符串类别,TraceEventType类型,EventId ID,字符串前缀,字符串格式,Object [] args)“

It seems to me that my class is not thread safe as well the call to TraceData. 在我看来,我的课程以及对TraceData的调用也不是线程安全的。 But ConfigurableTextWriterTraceListener is said to thread safe after all. 但是据说ConfigurableTextWriterTraceListener毕竟是线程安全的。 However I checked IsThreadSafe propety for my TextWriterTraceListener derived class at run-time and it false. 但是,我在运行时检查了我的TextWriterTraceListener派生类的IsThreadSafe属性,它为false。 I am trying to figure out where the problem is. 我正在尝试找出问题所在。

It means what says - your TraceListener is not thread safe and breaks when accessed from several threads. 这意味着说什么-您的TraceListener不是线程安全的,并且从多个线程访问时会中断。 You need to make your listeners thread safe or find a way to ensure that only one thread accesses any particular instance. 您需要使您的侦听器线程安全,或找到一种方法来确保只有一个线程可以访问任何特定实例。

One way to make them thread safe is to use a synchronized queue and make all your calls enqueue data items to the queue while the 'real' traceListener dequeues them and writes them out in a separate thread. 使它们线程安全的一种方法是使用同步队列并使所有调用将数据项排队到队列中,而“真实” traceListener使它们出队并在单独的线程中将它们写出。

You also have to be careful with your dictionary of listeners - updating the dictionary is not thread safe, but if you never access it before the last update is applied, you can leave it as is 您还必须注意侦听器的字典-更新字典不是线程安全的,但是如果在应用上一次更新之前从未访问过字典,则可以按原样保留它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM