简体   繁体   中英

c# - Process cannot access file because it is used by another process

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

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;
}

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

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.

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(); 
}

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM