0

Im using the following to empty a txt file:

System.IO.File.WriteAllText(path, string.Empty);

The problem becomes when i run to many threads at once and they try to access the file at the same time..

Any ideas on an easy fix? :)

Elvin
  • 367
  • 3
  • 5
  • 16
  • possible duplicate http://stackoverflow.com/questions/1632470/accessing-a-single-file-with-multiple-threads – Daniel Casserly Nov 27 '12 at 11:00
  • What is the file used for? Solutions would seem to be locking the file or not using the same filename for all of them. Your usage will probably determine which is most appropriate so it would help if we could have more context... Why would you be emptying a file that something else might be using already for example? might it have put content in there that you don't actually want cleared? – Chris Nov 27 '12 at 11:01
  • All threads share the same info to be saved, and i dont want duplicate info to be saved – Elvin Nov 27 '12 at 11:02
  • @DanielCasserly how is this a duplicate? the question here is tagged as C# and your link points to a delphi question – Stefan P. Nov 27 '12 at 11:02
  • I want to keep saving it cause if the program crashed ill still have some of the info – Elvin Nov 27 '12 at 11:02
  • 1
    @DanielCasserly: Similar perhaps but different language so not really a duplicate (since the delphi code there doesn't help a c# programmer solve the problem). – Chris Nov 27 '12 at 11:03
  • My bad. Didn't read it through thoroughly enough. Sorry :-( – Daniel Casserly Nov 27 '12 at 11:16

3 Answers3

1

Multi-threading to the rescue!

You should use a Monitor, AutoResetEvent or lock block (actually it's a Monitor) in order to synchronize access to the whole file.

public class SomeClass
{
     private readonly static object _sync = new object(); 

     public void WriteAllText()
     {
          lock(_sync)
          {
               File.WriteAllText("myfile.txt", "Hello world from a synchronized file access!!!");
          }
     }
}

}

This way you're preventing multiple threads to access the same file at the same time.

Learn about lock block here:

http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.110).aspx

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
0

You should probably look into FileStream. There's a good example of what you're trying to do here.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
gaynorvader
  • 2,619
  • 3
  • 18
  • 32
  • I've a question: does `FileStream.WriteAsync` waits until it can get a lock in the target file or it does it asynchronously but once it tries to write the file, if it's locked, throws an exception? It's an important point. – Matías Fidemraizer Nov 27 '12 at 11:18
  • I'm not sure I understand what you mean. If the file is locked for editing, a meaningful exception is thrown. `FileStream.CanWrite` should be used to check if the file is ready for writing. – gaynorvader Nov 27 '12 at 11:31
  • So, at the end of the day, how does your answer *answers* to the question? Using `FileStream` async doesn't solve the multi-threaded access to files. You still need to synchronize file access. – Matías Fidemraizer Nov 27 '12 at 11:37
0

Another approach I would consider is to have a single writer thread serviced by a queue. All other threads that want to write to the file do this by adding text items to the end of the queue. The writer thread removes text items from the front of the queue and writes them to the file. You use the lock statement to synchronise access to the queue object, and a AutoResetEvent object to signal the writer thread when you add stuff to the queue, to let it know that there is something in the queue for it to process.

Polyfun
  • 9,479
  • 4
  • 31
  • 39
  • Basically it's my answer's approach. Such queue implicitly exists when you enter to a synchronized block, but it's handled by the operating system. Why duplicating it? – Matías Fidemraizer Nov 27 '12 at 11:19