views:

92

answers:

2

When I execute the code below, I get the common exception The process cannot access the file *filePath* because it is being used by another process.

What is the most efficient way to allow this thread to wait until it can safely access this file?

Assumptions:

  • the file has just been created by me, so it is unlikely that another app is accessing it.
  • more than one thread from my app might be trying to run this code to append text to the file.

:

 using (var fs = File.Open(filePath, FileMode.Append)) //Exception here
 {
     using (var sw = new StreamWriter(fs))
     {
         sw.WriteLine(text);
     }
 }

So far, the best that I have come up with is the following. Are there any downsides to doing this?

    private static void WriteToFile(string filePath, string text, int retries)
    {
        const int maxRetries = 10;
        try
        {
            using (var fs = File.Open(filePath, FileMode.Append))
            {
                using (var sw = new StreamWriter(fs))
                {
                    sw.WriteLine(text);
                }
            }
        }
        catch (IOException)
        {
            if (retries < maxRetries)
            {
                Thread.Sleep(1);
                WriteToFile(filePath, text, retries + 1);
            }
            else
            {
                throw new Exception("Max retries reached.");
            }
        }
    }
+2  A: 

If you have multiple threads attempting to access the same file, consider using a locking mechanism. The simplest form could be:

lock(someSharedObject)
{
    using (var fs = File.Open(filePath, FileMode.Append)) //Exception here
    {
        using (var sw = new StreamWriter(fs))
        {
            sw.WriteLine(text);
        }
    }
}

As an alternative, consider:

File.AppendText(text);
kbrimington
A: 

You can set a FileShare to allow multiple access with this File.Open command like

File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)

But i think the cleanest way if you have multiple threads that are trying to write into one file would be to put all these messages into a Queue<T> and have one additional thread that writes all elements of the queue into the file.

Oliver