3

I'm using this code for saving logs in may C# monotouch application:

public static void  writeExeption(string message){
        string path= StorageClass .LogsPath ;
        string filepath= Path.Combine (path ,"Log.txt");
        if(!File.Exists (filepath )){
            using (StreamWriter sw = File.CreateText(filepath)) 
            {
                sw.WriteLine ("--------------------------------------------------------------------------" +
                              "--------------------");
                sw.WriteLine("blahblah...");
                sw.WriteLine ("--------------------------------------------------------------------------" +
                              "--------------------");
            }   
        }
        using (StreamWriter w = File.AppendText(filepath ))
        {
            Log(message , w);
        }
    }

    public static void Log(string logMessage, TextWriter w)
    {
        w.Write("\r\nLog Entry : ");
        w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
                    DateTime.Now.ToLongDateString());
        w.WriteLine("  :");
        w.WriteLine("  :{0}", logMessage);
        w.WriteLine ("--------------------------------------------------------------------------" +
                      "--------------------");
    }

But in the application I get this error:

 Sharing violation on path 'File Path'
Konrad Morawski
  • 8,307
  • 7
  • 53
  • 91
Husein Behboudi Rad
  • 5,434
  • 11
  • 57
  • 115
  • 1
    **1**. On which line? And what have you tried so far? **2.** Possible duplicate of http://stackoverflow.com/questions/11541244/sharing-violation-on-path-error-c-sharp as well as http://stackoverflow.com/questions/14313303/file-sharing-violation-occurs-after-creation-of-file – Konrad Morawski May 15 '13 at 09:12
  • line " w.WriteLine(" :{0}", logMessage);" . I tried http://stackoverflow.com/questions/3817477/simultaneous-read-write-a-file-in-c-sharp and http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/52f4f8fb-a434-4660-9806-3a30e3bbffb2 but not working for me. Also i see the link you sent now. – Husein Behboudi Rad May 15 '13 at 09:21
  • If you want to do logging in .net, you should use one lightweight framework like log4net or Nlog, they handle all the file access and thread syncing for you. Don't try to write it yourself. – Peter May 15 '13 at 09:21
  • Do you have the `Log.txt` open in some other application while you are trying to execute your application? – Alex Filipovici May 15 '13 at 09:35
  • @AlexFilipovici actually it is an iphone app, and no I have not open this document – Husein Behboudi Rad May 15 '13 at 10:03
  • @peer can you describe me how to use these libraries that you said? Do you know are they available on xamarin? Maybe a link of a tutorial help. Thanks – Husein Behboudi Rad May 15 '13 at 10:03
  • Have a look a the log4net pages: http://logging.apache.org/log4net/ – Peter May 16 '13 at 12:55

2 Answers2

1

Seems like you're accessing one file in two or more places (could be in different threads).

Use these methods to read/write files in multi-thread apps to avoid such error:

    /// <summary>
    /// Writes the file exclusively. No one could do anything with file while it writing
    /// </summary>
    /// <param name="path">Path.</param>
    /// <param name="data">Data.</param>
    public static void WaitFileAndWrite(string path, byte[] data)
    {
        while (true) {
            Stream fileStream = null;

            try {
                // FileShare.None is important: exclusive access during writing
                fileStream = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None);
                fileStream.Write(data, 0, data.Length);

                break;
            } catch (IOException ex) {
                Console.WriteLine (ex);
                Thread.Sleep(10);
            } finally {
                if (fileStream != null) {
                    fileStream.Close();
                }
            }
        }
    }

    /// <summary>
    /// Waits the file and read.
    /// </summary>
    /// <returns>The file and read.</returns>
    /// <param name="fileName">File name.</param>
    public static byte [] WaitFileAndRead(string fileName)
    {
        byte[] result = null;

        if (File.Exists(fileName)) {
            while (true) {
                Stream fileStream = null;

                try {
                    fileStream = File.OpenRead(fileName);
                    var length = fileStream.Length;
                    result = new byte[length];
                    fileStream.Read(result, 0, Convert.ToInt32(length));
                    break;
                } catch (IOException ex) {
                    Console.WriteLine (ex);
                    Thread.Sleep(10);
                } finally {
                    if (fileStream != null) {
                        fileStream.Close();
                    }
                }
            }
        }

        return result;
    }
}

Yet you should be accurate. If someone open file for read/write operations and don't close it, these method will try to open infinitely.

Maxim Korobov
  • 2,574
  • 1
  • 26
  • 44
1

Try adding to enclose the StreamWriter which appends the data in a lock statement. First, add an object to refer to:

static object _locker = new object();

Then, modify the writeExeption method by locking the last using statement:

lock (_locker)
{
    using (StreamWriter w = File.AppendText(filepath))
    {
        Log(message, w);
    }
}

If this still doesn't work, it means that some other application is using your file. If it works, it means that you are logging on multiple threads.

Alex Filipovici
  • 31,789
  • 6
  • 54
  • 78