Reputation: 30837
I have a text file and multiple threads/processes will write to it (it's a log file).
The file gets corrupted sometimes because of concurrent writings.
I want to use a file writing mode from all of threads which is sequential at file-system level itself.
I know it's possible to use locks (mutex for multiple processes) and synchronize writing to this file but I prefer to open the file in the correct mode and leave the task to System.IO
.
Is it possible ? what's the best practice for this scenario ?
Upvotes: 4
Views: 2346
Reputation: 133950
To my knowledge, Windows doesn't have what you're looking for. There is no file handle object that does automatic synchronization by blocking all other users while one is writing to the file.
If your logging involves the three steps, open file, write, close file, then you can have your threads try to open the file in exclusive mode (FileShare.None
), catch the exception if unable to open, and then try again until success. I've found that tedious at best.
In my programs that log from multiple threads, I created a TextWriter
descendant that is essentially a queue. Threads call the Write
or WriteLine
methods on that object, which formats the output and places it into a queue (using a BlockingCollection
). A separate logging thread services that queue--pulling things from it and writing them to the log file. This has a few benefits:
Doing this across processes would be a lot more difficult. I've never even considered trying to share a log file across processes. Were I to need that, I would create a separate application (a logging service). That application would do the actual writes, with the other applications passing the strings to be written. Again, that ensures that I can't screw things up, and my code remains simple (i.e. no explicit locking code in the clients).
Upvotes: 2
Reputation: 612794
Your best bet is just to use locks/mutexex. It's a simple approach, it works and you can easily understand it and reason about it.
When it comes to synchronization it often pays to start with the simplest solution that could work and only try to refine if you hit problems.
Upvotes: 4
Reputation: 4778
you might be able to use File.Open()
with a FileShare
value set to None
, and make each thread wait if it can't get access to the file.
Upvotes: 0