Hi
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. 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. Basically there are only console and text file listeners. What TraceData does it takes the category name (i.e. logging start-up) and finds the right listener. 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
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."
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)"
It seems to me that my class is not thread safe as well the call to TraceData. But ConfigurableTextWriterTraceListener is said to thread safe after all. However I checked IsThreadSafe propety for my TextWriterTraceListener derived class at run-time and it false. I am trying to figure out where the problem is.