1

This is the scenario, I have an application that overwrites an xml file every 2secs. And then I have this c# application, that reads this file every 1-2secs. this process runs fine, but there are times when i get the error saying,

Process cannot access file because it is used by another process

I am using xmldocument.load to open and read the xml file.

What can i do to solve this issue? I have tried running on different machines, and this is absolutely random, as on my machine, it ran for 6 hours before the error, on another machine,

Coz my c# program will continue reading this file, unless the user click a button to stop the data logging process

As i want the program to continue running as long as the user doesn't stop it. Please help

5
  • What's the other process? We can't see it from here. Sleep and try again, I suppose. Commented Mar 3, 2012 at 15:17
  • I am the application that is writing the file is the problem?? Commented Mar 3, 2012 at 15:30
  • You're reading your own files every second? Is this some kind of hard disk endurance test? Post code that demonstrates that you are properly disposing the writer. Commented Mar 3, 2012 at 15:43
  • If you are doing all this in order to communicate between two applications, it's wrong. There are many better ways to send information from one application to another: WPF (or Remoting in older .NET versions), plain sockets, whatever. Using a file to communicate is a wrong idea. Commented Mar 3, 2012 at 15:49
  • i was thinking of converting it to use socket.. but the source is bound to use that method unfortunately.. Commented Mar 3, 2012 at 18:46

7 Answers 7

6

Please tell have you tried reading XmlDocument content using FileStream variable which was instantiated with appropriate FileMode and FileAccess and FileShare parameters using specialy designated constructor. You can load content of XmlDocument using implementation of Load method which takes appropriately openned (for write with share of read access of vice versa) filestream as parameter.

Please try using following code for writing to file:

XmlDocument xmlDocument = new XmlDocument();
using (FileStream fileStream = new FileStream("C:\\test.xml", FileMode.Append, FileAccess.Write, FileShare.Read))
{
    xmlDocument.Load(fileStream);
}

and following code for reading from file:

XmlDocument xmlDocument = new XmlDocument();
int attempts = 5;
Exception cannotReadException = null;
while (attempts > 0)
{
    try
    {
        using (FileStream fileStream = new FileStream("C:\\test.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            xmlDocument.Load(fileStream);
            attempts = 0;
        }
    }
    catch (Exception exception)
    {
        cannotReadException = exception;
        System.Threading.Thread.Sleep(100);
        attempts--;
    }
}

if (cannotReadException != null)
{
    throw cannotReadException;
}
Sign up to request clarification or add additional context in comments.

1 Comment

@Fahad.ag Please try opening .xml file for write with FileShare.Read and for write with FileShare.ReadWrite - as in updated answer.
0

You cannot read from file when that another application write to that same file, if you have develop both applications I would reccomend real database instead XML file. For excample SQLite.

But if you won't to use xml files you can catch exception that XmlDocument.Load throws and try to read again hoping that other process is done with writting

Comments

0

The file is either still marked in use by your operating system, in use by another computer or in use by your virus scanner at times and isn't freed fast enough for your program. You should either insert a small timeout/delay or catch the exception using a try .. catch and retry after, again, a small delay.

Comments

0

When you use a timer you should stop timer when you process on a file until you finish:

private void timer_Tick(object sender, EventArgs e)
{
  try
  {
    timer.Stop();
    //read write whatever ...
  }
  catch(){}  
  timer.start(); 
}

Comments

0

To avoid conflicts do your overwriting like this:

  • write the new XML to a temporary file in same location as old XML
  • rename new file to old file

on UNIX file systems this will avoid problem of read attempts failing during the write. Not sure about windows, but should work.

Comments

0

To expand on what others have suggested, here is an example of how you may implement using a try catch block to resolve the conflict:

private XmlDocument OpenXML(string filename, int retryCount = 0)
{
    XmlDocument retval = new XmlDocument();

    try
    {
        retval.Load(filename);
    }
    catch
    {
        if (retryCount < 5)
        {
            retval = OpenXML(filename, retryCount + 1);
        }
        else
        {
            return null;
        }
    }

    return retval;
}

In the catch you could add a pause if needed, or increase the number of retry attempts / deal with it differently when the maximum number of attempts has been reached.

Comments

0

As already suggested, you could implement a simple wait-for-x-(milli)seconds-and-retry approach.

If you're on Windows and have access to the sources of both programs, you could use the native Win32 functions to create a semaphore to regulate access to the file. See this page for more details.

2 Comments

what if i use this on the application that generates the XML file fo = _fsopen(filename, openStr,_SH_DENYNO );, will this have any effect on the app thats trying to real the file?
I haven't used _fsopen much, but the documentation leads me to believe that it would work. If you're going this route, I feel calling _fsopen with _SH_DENYRW flag in the program that reads the XML file and _SH_DENYNO flag in the program that writes it should work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.