Hi, I'm building a windows service in C# which performs a file watch on a specific folder and spawns a thread for each found file for it's processing. The problem I encountered was that all threads (working on different individual files) write data exception problems with file into a common log file. The log file is a plain text file and it is opened using StreamWriter and closed immediately after writing to it.
When I drop 20+ files in the file watch folder at the same time, the service spawns 20+ threads and somewhere down the line, I get an exception for log file write as it is being used by the other thread.
So I ended up leveraging the built-in Trace class to do the logging to a text file by adding a listener component. Now after dropping 50 or 100 files, the log file never gets contention error and everything looks perfect.
Now here is my question to C# experts: Is it ok to use Trace class for logging the application data problem even though it is designed for debugging purposes? Any performance issues, etc?
Thanks.
AlanPosted Oct 31, 2007, 1:01 PM
Just as a matter of interest, I thought I'd have a look at the internals of the Trace class using Reflector and the thread synchronization is in fact achieved by liberal use of the lock() statement in all of the Write, Flush, Close etc methods.
But the Trace class does all the work for you and so, yes , it does seem like a good way to implement logging when multiple concurrent threads can write to the file :)
JayakrishnaPosted Oct 31, 2007, 11:12 AM
Alan, Thanks for your comments.
The beauty of Trace class (from what I've seen in my testing and reading various articles) is completely thread-safe. When 20 different threads are trying to log an entry using the Trace class, it automatically waits (using some low-level built polling mechanism, thanks to .NET architecture) if other thread is currently writing to the log file. I did not see any locking or contention issues so far when multiple threads are running concurrently. Note that the log file created by Trace class is completely readable by external application such as NotePad while the threads are actually writing to it. As long as the service is running, the log file is not deletable however you can view it without any problem. The reason is that the Trace class is actually holding the file with exclusive access but readable by other applications (I guess it is FileShare=Read) until the service is brought down.
So for right now, everything is fine with Trace log file in my application. I'm happy with the results so far.
Thanks again for your comments.
AlanPosted Oct 31, 2007, 10:10 AM
Well, MS designed the Trace class for runtime diagnostics and, whilst there is inevitably some overhead in using it for other purposes, such as logging, I wouldn't expect this to be too serious as writing to disk is a relatively slow operation in any case.
However, possibly all you needed to prevent the various threads attempting to write to the log file at the same time was a mechanism such as C#'s lock() statement which, if you're not familiar with it, is described here:
http://msdn2.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx
JayakrishnaPosted Oct 31, 2007, 9:29 AM
Can anyone comment on this thread please?