Hello everyone...
I'm working with a multi-threaded application. I believe I have it to the point now where several different threads can write to one common log file. Writing to the log would be used at initial startup and for an occasional exception, and is not something that would not happen very often.
What I'd like some advise on is making sure the act of writing to the log is thread safe, in that when a thread writes to the one log file:
1. A single writeline statement completes correctly and definately gets written to the physical log file ASAP and
2. If I have multiple writeline statements that I want to have printed sequentially from the same thread, they come out as an organized group - they are not intermixed with information from other threads. For example:
Thread 1
=======
WriteLine("ThreadOne says Have a Really Nice Day");
WriteLine("ThreadOne says Drink Dr. Pepper");
Thread 2
=======
WriteLine("ThreadTwo says Have a Nice Day");
WriteLine("ThreadTwo says Drink 7 Up");
What I want to make sure the log to looks like is:
ThreadOne says Have a Really Nice Day
ThreadOne says Drink Dr. Pepper
ThreadTwo says Have a Nice Day
ThreadTwo says Drink 7 Up
I'm using the following to work with my log file:
public class StaticLog{
private static String myFullLogFileName; private static StreamWriter myLogFile; public void CreateStaticLog(){
myFullLogFileName =
@"C:\lotsoffun.log"; myLogFile = new StreamWriter(myFullLogFileName);myLogFile.AutoFlush =
true;}
public static StreamWriter MyLogFile{
// Return the Log File Object get{
lock (myLogFile){
return myLogFile;} // lock
} // get
}
// Property MyLogFile} // Class
From each thread, when I go to write to the log:
public class ClientMgr{
StreamWriter funLogFile;public ClientMgr()
{
funLogFile = StaticLog.MyLogFile;}
// Constructor...... Later on in a method ...
// perhaps a lock statement goes here
funLogFile.WriteLine("First Statement);
funLogFile.WriteLine("Second Statement);
.... etc.
I did see mention of TextWriter.Synchronization, but couldn't quite figure out if that would help, or how to implement that one. I was thinking of just using a lock statement on the funLogFile just before the WriteLines.
Thanks for any suggestions!
DB

Multiple Threads and Synchronizing Output to a Log File
Milow
I do not recommend that you group log lines together, as you could seriously cripple the performance of your application. Writing to files is SLOW, and you do not want to block other threads whilst you write out 10 lines to the log; blocking for one line is bad enough. Just include the thread id in each line, then you can use something like Excel to load the log and sort/filter on the thread id.
Also, rather than reinventing the wheel, check out log4net (use google to find it). This is a very good .Net logger, and saves you all the hassle of writing this code yourself.
schalmeti
DrBob
The lock statement you have in the MyLogFile getter won't help. The lock is released as soon as you exit from the lock statement block.
One way to do this is to create a class which implements the IDisposable pattern to group log writing statements - let's call it LogGrouper as I can't think of a better name just now.
Your app would call it something like the following:
using(LogGrouper lg = new LogGrouper())
{
lg.WriteLine(line1);
lg.WriteLine(line2);
}
The LogGrouper "WriteLine" method would simply concatenate log data to a private StringBuilder object.
The Dispose method would call the underlying logging write method to actually output the data.
Sachin1979
Or you could create a LogMessage object. Then pass it to your Logger.log(LogMessage message) method. The LogMessage could have a series of function for appending data (like LogMessage.AddLine(string), etc).
Declare your Logger.Log(LogMessage) as static (shared in VB). Also declare a private static Object m_lock = new Object(); within the Logger class.
Your log method would then get a lock on the m_lock variable and write the LogMessage object out to the file.
This guarantees that all messages related to a single exception or event of merit gets logged together.