这是场景, 我有一个应用程序每2秒覆盖一个xml文件。 然后我有这个c#应用程序,每1-2秒读取一次该文件。 这个过程运行良好,但有时我会收到错误说,
进程无法访问文件,因为它由另一个进程使用
我正在使用xmldocument.load打开并读取xml文件。
我该怎么做才能解决这个问题? 我试过在不同的机器上运行,这绝对是随机的,就像在我的机器上,它在错误之前运行了6个小时,在另一台机器上,
Coz我的c#程序将继续读取此文件,除非用户单击按钮停止数据记录过程
因为我希望程序能够继续运行,只要用户不停止它。 请帮忙
答案 0 :(得分:6)
请告诉我您是否尝试使用XmlDocument变量阅读FileStream内容,该变量使用特定FileMode和FileAccess以及FileShare参数进行实例化,并使用specialy指定的{{ 3}}。您可以使用constructor方法的实现来加载XmlDocument的内容,该方法需要适当地打开(对于具有读取访问权限的共享,反之亦然)文件流作为参数。
请尝试使用以下代码写入文件:
XmlDocument xmlDocument = new XmlDocument();
using (FileStream fileStream = new FileStream("C:\\test.xml", FileMode.Append, FileAccess.Write, FileShare.Read))
{
xmlDocument.Load(fileStream);
}
以及以下代码从文件中读取:
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;
}
答案 1 :(得分:1)
当另一个应用程序写入同一个文件时,你无法从文件中读取,如果你开发了两个应用程序,我会推荐真正的数据库而不是XML文件。对于例子SQLite。
但是如果你不使用xml文件,你可以捕获XmlDocument.Load抛出的异常,并尝试再次阅读,希望其他进程完成写入
答案 2 :(得分:0)
该文件仍然被您的操作系统标记为正在使用,被另一台计算机使用或者有时被您的病毒扫描程序使用,并且没有足够快的程序释放。您应该插入一个小的超时/延迟,或者使用try .. catch捕获异常,然后再次尝试重新尝试。
答案 3 :(得分:0)
当您使用计时器时,您应该在处理文件时停止计时器,直至完成:
private void timer_Tick(object sender, EventArgs e)
{
try
{
timer.Stop();
//read write whatever ...
}
catch(){}
timer.start();
}
答案 4 :(得分:0)
为了避免冲突,请按照以下方式进行覆盖:
在UNIX文件系统上,这将避免在写入期间读取尝试失败的问题。不确定窗口,但应该工作。
答案 5 :(得分:0)
为了扩展其他人的建议,下面是一个如何使用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;
}
在捕获中,您可以根据需要添加暂停,或者在达到最大尝试次数时以不同方式增加重试次数/处理次数。
答案 6 :(得分:0)
如前所述,您可以实现一种简单的等待x(毫)秒重试方法。
如果您使用的是Windows并且可以访问这两个程序的源代码,则可以使用本机Win32函数创建信号量来管理对文件的访问。有关详细信息,请参阅this页面。