If you don't want to restructure your code dramatically like I suggested in my other answer, you could try this, which assumes your LogManager class has:
- a static thread-safe queue,
_SynchronizedQueue - a static object to lock on when writing,
_WriteLock
and these methods:
public static void Log(string message) { LogManager._SynchronizedQueue.Enqueue(message); ThreadPool.QueueUserWorkItem(LogManager.Write(null)); } // QueueUserWorkItem accepts a WaitCallback that requires an object parameter private static void Write(object data) { // This ensures only one thread can write at a time, but it's dangerous lock(LogManager._WriteLock) { string message = (string)LogManager._SynchronizedQueue.Dequeue(); if (message != null) { // Your file writing logic here } } }
There's only one problem: the lock statement in the Write method above will guarantee only one thread can write at a time, but this is dangerous. A lot can go wrong when trying to write to a file, and you don't want to hold onto (block) thread pool threads indefinitely. Therefore, you need to use a synchronization object that lets you specify a timeout, such as a Monitor, and rewrite your Write method like this:
private static void Write() { if (!Monitor.TryEnter(LogManager._WriteLock, 2000)) { // Do whatever you want when you can't get a lock in time } else { try { string message = (string)LogManager._SynchronizedQueue.Dequeue(); if (message != null) { // Your file writing logic here } } finally { Monitor.Exit(LogManager._WriteLock); } } }