1

I have a WinForm application developed in C# which looks for a file in my local drive and if it doesn't find it then creates it else add some text in the file and then read it.

How can I synchronize this if I run the two instances of my app from two different folders on the same machine?

I want the other instance not to interrupt when the first instance is working on the file. Please note that as both are the instances of the same application, they work on same target folder to read-write the file.

Is there any threading technique needs to be implemented?

SSingh
  • 199
  • 2
  • 11
  • 2
    I'm not sure, but you might be looking at mutexs. Possibly a relevant stackoverflow answer: http://stackoverflow.com/questions/9077573/using-a-named-mutex-to-lock-a-file – Matthew May 17 '13 at 17:17
  • What do you want synchronize what between two app? data load from file? variables? or something special? – Toan Vo May 17 '13 at 17:17
  • Please explain what problems you have with the most basic approach of "open file/write data/close, retry if file is locked". – Alexei Levenkov May 17 '13 at 17:22
  • 1
    Don't forget to make your mutexes global! http://stackoverflow.com/questions/2830546/cross-user-c-sharp-mutex – Lily May 17 '13 at 17:22
  • Haven't you people heard of file sharing modes? There is no need for mutexes or other synchronization primitives here. The file system has built in functionality to handle this common situation. – Jim Mischel May 17 '13 at 19:33

4 Answers4

1

No need for synchronization primitives. You should be able to open the file for exclusive access. That will prevent any other app from messing with it. For example:

try
{
    using (var fs = new FileStream("foo", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
    {
        try
        {
            // do stuff with file.
        }
        catch (IOException ex)
        {
            // handle exceptions that occurred while working with file
        }
    }
}
catch (IOException openEx)
{
    // unable to open file
}

Specifying FileShare.None will prevent any other application from accessing the file while you have it open.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
0

I think the most simple solution would be to use StreamReader and StreamWriter surrounded with try catch. If one instance have opened the file, another instance will throw an exception

  try
  {
    using (StreamWriter sw = new StreamWriter("my.txt", true))
    {
      sw.WriteLine(dir.Name);
    }
  }
  catch
  {
      //maybe retry in 5 seconds
  }
VladL
  • 12,769
  • 10
  • 63
  • 83
0

You could use a named system-wide mutex, but that has the problem that another process might have the file in use (e.g., the user, for instance). The filesystem is all the synchronization you need. Something like this should do you:

static bool AddTextToFile( string someText , int maxAttempts )
{
    if ( string.IsNullOrWhiteSpace(someText) ) throw new ArgumentOutOfRangeException( "someText"    ) ;
    if ( maxAttempts < 0                     ) throw new ArgumentOutOfRangeException( "maxAttempts" ) ;

    bool success = false ;
    int  attempts = 0 ;

    while ( !success )
    {
        if ( maxAttempts > 0 && ++attempts > maxAttempts ) { break ; }
        try
        {
            using ( Stream       s = File.Open( @"c:\log\my-logfile.txt" , FileMode.Append , FileAccess.Write , FileShare.Read ) )
            using ( StreamWriter sw = new StreamWriter(s,Encoding.UTF8) )
            {
                sw.WriteLine("The time is {0}. The text is {1}" , DateTime.Now , someText );
                success = true ;
            }
        }
        catch (IOException)
        {
            // the file is locked or some other file system problem occurred
            // sleep for 1/4 second and retry
            success = false ;
            Thread.Sleep(250);
        }
    }

    return success ;
}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
0

You might want to look at mutex. They allow you to do cross process locking. While one mutex is open on a program, the one in the other program will wait.

the_lotus
  • 12,668
  • 3
  • 36
  • 53