简体   繁体   English

有时 xml 文件内容在 C# 中消失

[英]Sometimes the xml file contents disappear in C#

It is very weird.这很奇怪。

My Program call the following method almost every 10 seconds.我的程序几乎每 10 秒调用一次以下方法。

public void System_Save_Xml(string SystemPath)
    {
        XmlDocument doc = new XmlDocument();
        XmlElement xmlSystem = doc.CreateElement("System");

        XmlElement el_Option = doc.CreateElement("Option");
        el_Option.InnerText = Option;
        xmlSystem.AppendChild(el_Option);

        doc.AppendChild(xmlSystem);
        doc.Save(SystemPath);
    }
 public void System_Load_Xml(string SystemPath)
    {
        if (System.IO.File.Exists(SystemPath) == false) return;            

        XmlDocument doc = new XmlDocument();
        doc.Load(SystemPath);

        XmlNode el_Option = doc.SelectSingleNode("//System/Option");
        if (el_Port_LightCtr != null)
        {
            Option = el_Option.InnerText;
        }
    }

This works well.这很好用。 But sometimes, very occasionally, the content of the xml file disappears.但有时,非常偶尔,xml 文件的内容会消失。 Xml file is exits but file has no content. Xml 文件已退出,但文件没有内容。 just empty.只是空的。 So the xml file load fails and an exception is thrown.所以xml文件加载失败,抛出异常。 -xml root element not found. -xml 未找到根元素。 I tried to print a message when it failed, but I couldn't catch.当它失败时,我试图打印一条消息,但我无法捕捉到。

Are there people who experienced the same symptoms as me?有没有和我有同样症状的人? Or can you guess what the problem is?或者你能猜出问题是什么吗?

My guess at the problem is that XmlDocument.Save does not work transactionally .我对这个问题的猜测是XmlDocument.Save不能以事务方式工作。

If the xml file already exists before System_Save_Xml runs, there will be a small period during the call where the file will be half-written.如果 xml 文件在System_Save_Xml运行之前已经存在,则在调用期间会有一小段时间文件将被写入一半。

Code reading the file at this time will not see the valid document that existed before, or the new updated document, but an invalid one.此时读取文件的代码将不会看到之前存在的有效文档,也不会看到新更新的文档,而是无效的。

In the cases I've seen it will have a bunch of 0 bytes written to the file.在我见过的情况下,它将有一堆 0 字节写入文件。 You should be able to use a try-catch around doc.Load to capture the exact error message you are getting and (with a bit more work) find the state that the file is in to cause it.您应该能够在 doc.Load 周围使用doc.Load来捕获您收到的确切错误消息,并(通过更多工作)找到文件所在的 state 导致它。

If my guess is right, its a kind of race condition that you can solve with:如果我的猜测是正确的,它是一种你可以解决的竞争条件:

  • A lock in your code so that the file isn't loaded while Save is executing (eg if you have no other code that's potentially reading during the Save call)锁定您的代码,以便在执行 Save 时不加载文件(例如,如果您在 Save 调用期间没有可能读取的其他代码)
  • An exclusive file system lock on the save process (do the save yourself with a stream and XmlWriter)保存过程中的独占文件系统锁定(使用 stream 和 XmlWriter 自己进行保存)
  • Save new data to a temporary "update" file and use File.Replace to update the main file将新数据保存到临时“更新”文件并使用File.Replace更新主文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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