Instead of creating a thread queue, why not create a queue of messages that are going to be written? So it could have a unique thread that wrote the messages and avoided the problem of access, thus creating a producer / consumer system.
The steps, roughly speaking, would be:
Put the log writing code inside an action;
Put this action in blocking collection
;
Have a% of dedicated logging that consumes thread
and execute the received actions, thus guaranteeing the sequential writing of the logs in the file;
An implementation based on the points back:
var LogCollection = new BlockingCollection<Action>();
public static void LogMessage(string messageToLog)
{
LogCollection.Add(() => File.WriteAllText("", messageToLog));
}
public static void WriteLogMessages(CancellationToken token)
{
foreach (var msg in LogCollection.GetConsumingEnumerable(token))
{
msg();
}
}
Using it would look like this:
public static void Main()
{
using (CancellationTokenSource cts = new CancellationTokenSource())
{
Thread t1 = new Thread(() => WriteLogMessages(cts.Token));
t1.Start();
LogMessage("Hello World");
Console.ReadKey();
cts.Cancel();
t1.Join();
}
}
Note:
For more ideas, and if you're determined to use your own log implementation, take a look at the NLog code for more inspiration.