Xaqron
Xaqron

Reputation: 30837

Synchronize writing to a file at file-system level

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

Answers (3)

Jim Mischel
Jim Mischel

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:

  • Threads don't have to wait on each other in order to log
  • Only one thread is writing to the file
  • It's trivial to rotate logs (i.e. start a new log file every hour, etc.)
  • There's zero chance of an error because I forgot to do the locking on some thread

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

David Heffernan
David Heffernan

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

vlad
vlad

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

Related Questions