c# -进程不能访问文件,因为它被另一个进程使用。

时间:2022-07-28 16:08:46

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,

这是一个场景,我有一个应用程序,每2secs覆盖一个xml文件。然后是c#应用程序,每1-2secs读取这个文件。这个过程运行得很好,但有时我得到错误的答案,

Process cannot access file because it is used by another process

进程不能访问文件,因为它被另一个进程使用

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

我使用xmldocument。加载以打开和读取xml文件。

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,

我能做些什么来解决这个问题?我试过在不同的机器上运行,这绝对是随机的,在我的机器上,它在出错前运行了6个小时,在另一台机器上,

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

因为我的c#程序将继续读取这个文件,除非用户单击一个按钮来停止数据日志记录过程

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

正如我希望程序继续运行,只要用户不停止它。请帮助

7 个解决方案

#1


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.

请告知您是否尝试使用FileStream变量读取XmlDocument内容,该变量使用特定的FileMode和FileAccess和FileShare参数进行实例化,使用特殊的指定构造函数。您可以使用load方法的实现来加载XmlDocument的内容,该方法以适当的openned(用于写入,反之亦然)filestream作为参数。

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

#2


1  

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.

当另一个应用程序写入同一个文件时,您无法从文件中读取数据,如果您开发了两个应用程序,那么我将重新编译真实的数据库,而不是XML文件。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

但是如果不使用xml文件,可以捕获XmlDocument的异常。加载抛出并尝试再次阅读,希望其他过程已经完成

#3


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.

该文件仍然被标记为您的操作系统使用,在另一台计算机使用或您的病毒扫描器在使用时,并没有释放足够快的您的程序。您应该插入一个小的超时/延迟或使用try捕获异常。再接再试,再一次,小延迟。

#4


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

#5


0  

To avoid conflicts do your overwriting like this:

为了避免冲突,你应该这样写:

  • write the new XML to a temporary file in same location as old XML
  • 将新XML写入与旧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.

在UNIX文件系统中,这将避免在写入过程中出现读尝试失败的问题。对windows不太确定,但应该可以。

#6


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:

为了扩展其他人的建议,这里有一个示例,说明如何使用try catch块来解决冲突:

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.

在捕获中,如果需要,您可以添加一个暂停,或者增加重试尝试的次数/当尝试次数达到最大时,以不同的方式处理它。

#7


0  

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

如前所述,您可以实现一个简单的等待x-(milli)秒-重试方法。

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.

如果您在Windows上,并且可以访问两个程序的源代码,您可以使用本机Win32函数创建一个信号量来规范对文件的访问。详情请参阅本页。

#1


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.

请告知您是否尝试使用FileStream变量读取XmlDocument内容,该变量使用特定的FileMode和FileAccess和FileShare参数进行实例化,使用特殊的指定构造函数。您可以使用load方法的实现来加载XmlDocument的内容,该方法以适当的openned(用于写入,反之亦然)filestream作为参数。

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

#2


1  

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.

当另一个应用程序写入同一个文件时,您无法从文件中读取数据,如果您开发了两个应用程序,那么我将重新编译真实的数据库,而不是XML文件。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

但是如果不使用xml文件,可以捕获XmlDocument的异常。加载抛出并尝试再次阅读,希望其他过程已经完成

#3


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.

该文件仍然被标记为您的操作系统使用,在另一台计算机使用或您的病毒扫描器在使用时,并没有释放足够快的您的程序。您应该插入一个小的超时/延迟或使用try捕获异常。再接再试,再一次,小延迟。

#4


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

#5


0  

To avoid conflicts do your overwriting like this:

为了避免冲突,你应该这样写:

  • write the new XML to a temporary file in same location as old XML
  • 将新XML写入与旧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.

在UNIX文件系统中,这将避免在写入过程中出现读尝试失败的问题。对windows不太确定,但应该可以。

#6


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:

为了扩展其他人的建议,这里有一个示例,说明如何使用try catch块来解决冲突:

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.

在捕获中,如果需要,您可以添加一个暂停,或者增加重试尝试的次数/当尝试次数达到最大时,以不同的方式处理它。

#7


0  

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

如前所述,您可以实现一个简单的等待x-(milli)秒-重试方法。

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.

如果您在Windows上,并且可以访问两个程序的源代码,您可以使用本机Win32函数创建一个信号量来规范对文件的访问。详情请参阅本页。