I have implemented a logging method as follows:
ThreadPool.QueueUserWorkItem((state) => {
lock (appendLock) {
using (StreamWriter log = File.AppendText(_logFile)) {
log.WriteLine(message);
}
}
}, null);
1: Is the lock necessary? I wanted to thread the logging and found the lock already in place. So rather than alter that code, I simply wrapped into a worker delegate.
2: assuming the lock is required: is this the correct implementation to enqueue the delegate containing a lock? The potential is reasonably high that multiple threads could be requesting log-writes. By enqueueing the delegate to a worker thread, the length of a File I/O execution should not affect the application itself.
3: assume several logWriteDelegate workers have been enqueued: Will the delegates be invoked in the order they were received? i.e., Now serving #32 …Now serving #33
1: yes, lock it is required. It could be accessed by multiple threads, especially since you’re using the pool.
2: well, it’ll work. But it will keep the file locked making it hard to read. There are pre-existing logging frameworks that have worked a lot on this problem – it may be worth using me of them.
3: no; with the lock and the pool, that’s two separate reasons not to expect strict ordering in the final file. In fact, becuase of the pool, a single thread’s messages could appear out of order. If you want ordering, you’ll need to write to a (synchronized) queue, and have a dedicated worker that pulls data (synchronised) back out of the queue and writes to the log file. Again, existing logging frameworks will have solved this for you.