I have a logger class that handles various information display with pretty colors (yay.). However, since it writes to the console in separated steps (i.e. set color to red, write text, set color to gray, write text, for something that would render "[Error] Description..." with the error being in red), but I have a multithreaded application, so the steps can get mixed up and print random stuff in random colors.
I am aware of the lock
keyword, however it will not work with a static class such as the console.
Here is some example code if I was unclear:
using System;
using System.Text;
namespace N.Utilities.IO
{
public static class Logger
{
private static void WriteColored(string value, ConsoleColor color)
{
if (Logger.UseColor)
{
Console.ForegroundColor = color;
Console.Write(value);
Console.ForegroundColor = ConsoleColor.Gray;
}
else
{
Console.Write(value);
}
}
private static void WriteLineColored(string value, ConsoleColor color)
{
if (Logger.UseColor)
{
Console.ForegroundColor = color;
Console.WriteLine(value);
Console.ForegroundColor = ConsoleColor.Gray;
}
else
{
Console.Write(value);
}
}
private static bool useColor = true;
public static bool UseColor
{
get
{
return Logger.useColor;
}
set
{
Logger.useColor = value;
}
}
public static void Inform(string value)
{
Logger.WriteColored(" [Info] ", ConsoleColor.White);
Console.WriteLine(value);
}
public static void Warn(string value)
{
Logger.WriteColored(" [Warning] ", ConsoleColor.Yellow);
Console.WriteLine(value);
}
public static void Error(string value)
{
Logger.WriteColored(" [Error] ", ConsoleColor.Red);
Console.WriteLine(value);
}
}
To keep the console window open in Visual Studio without using the Console. ReadLine() method, you should run the application without debug mode by pressing Ctrl+F5 or by clicking on the menu Debug > Start without Debugging option. This way the application remains active below until the user presses a key.
The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.
A lock may be a tool for controlling access to a shared resource by multiple threads. Commonly, a lock provides exclusive access to a shared resource: just one thread at a time can acquire the lock and everyone accesses to the shared resource requires that the lock be acquired first.
There is no rule that makes the code thread safe, the only thing you can do is make sure that your code will work no matter how many times is it being actively executed, each thread can be interrupted at any point, with each thread being in its own state/location, and this for each function (static or otherwise) that ...
Your class needs:
private static readonly object ConsoleWriterLock = new object();
Then you can lock on this before writing to the console.
lock(ConsoleWriterLock)
{
//Your code here
}
The lock keyword will work with a static class, you just need to provide a static readonly
object to lock on.
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