raj
raj

Reputation: 353

Create a StreamReader/FileStream at the exact same time by two instances, throws exception File is being used by another process

I am reading a text file in a network location, based on FileWatcher events. I have two instances of the same program reading the file, when the instance 1 and 2 reads the file at the exact same seconds & milliseconds I am getting an exception saying File is being used by another process. When there is a few milliseconds difference between instance 1 and 2, this lock error is not coming.

Things which I have tried 1. Tried to use FileShare.ReadWrite parameter, still the issue occurs.

  1. Tried to make some delay between instance 1 and 2, but at sometime, issue occurs.

  2. Tried to use using statement in order to close FileStream objects, still the issue occurs.

Any thoughts/suggestions to avoid this issue.

Code Snippets

StreamReader sr = null;
FileStream fs = null;
try 
{
    fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
    sr = new StreamReader(fs);
    while (sr.Peek() != -1)
    {
     // Does only read operations no write.
    }
    sr.Close();
    fs.Close();
}
catch (Exception Ex)
{
    try
    {
        if (sr != null)
            sr.Close();
        if (fs != null)
            fs.Close();
    }
    catch (Exception innerException)
    {

    }  
 }

Upvotes: 0

Views: 118

Answers (2)

Rufus L
Rufus L

Reputation: 37070

One idea would be to use some kind of retry strategy and wrap your code in a try/catch. You can also put your fs and sr declarations in using statements so you don't have to worry about calling Close on them:

int retries = 3;

while (retries > 0)
{
    try
    {
        using (var fs = File.OpenRead(FileName))
        using (var sr = new StreamReader(fs))
        {
            while (sr.Peek() != -1)
            {
                // Does only read operations no write.
            }
        }

        break; // Exit the while loop if successful
    }
    catch
    {
        // Decrement our retry count and wait a bit if we're not done
        if (--retries > 0) Thread.Sleep(TimeSpan.FromSeconds(5));
    }
}

Upvotes: 1

Louis Ingenthron
Louis Ingenthron

Reputation: 1368

Hopefully someone can give you a cleaner answer, but if reading the file is critical, then I'd probably just throw it in a try/catch block, and wait a few milliseconds if it fails due to the lock before trying again.

Unfortunately, in larger systems with lots of disk activity, that approach may be detrimental to performance, but in a smaller system, it should work fine.

Upvotes: 0

Related Questions