I am working on multithreaded application(a server) which is basically a console application. In which I show processing log to console which is by default in white color. but on successful transaction I show the text in green and on unsuccessful transaction I show text in red. So I have three separate function in Program.cs for this.
For simple log
public static void Write(string text)
{
try
{
Console.Out.Write(text);
}
catch (Exception)
{ }
}
For unsuccessful transaction I change color to red, then print and then back to white
public static void WriteError(string text)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\t" + text);
Console.ForegroundColor = ConsoleColor.White;
}
For successful Transaction I change color to green, then print and then back to white
public static void WriteSuccess(string text)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\t" + text);
Console.ForegroundColor = ConsoleColor.White;
}
The problem is when more than 200 clients connected and the log of transactions of each client is printing on console. And when I change color like green for single line it cause many other lines of normal log to green as well. So please tell me how can I solve this problem.
If your class is the only one that is writing to the console, then locking on a single private object, as others mentioned, will work.
But if there are other writers, you will also need to synchronize with them, otherwise they could write while you're inside the lock. If you look at the implementation of Console
, you will notice that Console.Out
is a SyncTextWriter
, which synchronizes on itself (using [MethodImplAttribute(MethodImplOptions.Synchronized)]
). This means that if you use that as your synchronization object, you will be synchronized with other writers:
lock (Console.Out)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\t" + text);
Console.ForegroundColor = ConsoleColor.White;
}
This will still not work correctly if the other writers also set colors and use their own synchronization object. But it will work if the other writers also synchronize on Console.Out
.
The problem with this approach is that it relies on implementation details, but I'm not aware of any better solution.
There is your problem:
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\t" + text);
You set the color, another thread interrupts, sets the color to something else and then you print the text (in the wrong color).
You need to protect the section with a lock:
static object lockObj = new object();
public static void WriteError(string text)
{
lock(lockObj)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\t" + text);
Console.ForegroundColor = ConsoleColor.White;
}
}
The same thing you have to do for WriteSuccess(...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With