簡體   English   中英

為什么我的XDocument保存的文件不完整?

[英]Why is my XDocument saving an incomplete file?

我有一個使用線程運行一系列插件的程序。 在此過程中,它將插件的運行時寫入XDocument,以便程序知道自上次運行該插件以來已經有多長時間了。 不過,我遇到了問題。 加載XDocument時,大約每天(在不可預測的時間)一次,會出現以下錯誤:

[04/01/2013 08:17:10.083] Unexpected end of file has occurred. The following elements are not closed: Database, DatabaseList. Line 4043, position 1.

我運行了一些跟蹤語句,發現在此之前,該服務失敗,剩下大約44個插件無法運行,這顯然導致XDocument在關閉時未寫入文件末尾。 它可以讀寫硬盤上的XML文件,但是可以在內存中的XDocument上執行所有操作,因為我使用Linq對數據進行復雜的操作。

有人知道為什么會發生這種情況嗎? 我如何加載我的XDocument,以便在運行過程中發生某些事情時,它不會破壞實際文件?

編輯:這是利用XDocument (名為XDoc )的代碼示例:

    private void RunPlugin(object oQueuedPlugin)
    {
        PluginState oPluginState = (PluginState)oQueuedPlugin;
        PluginResponse oResponse = new PluginResponse();
        XElement xPlugin;

        lock (xDoc)
        {
            xPlugin = GetPluginNode(oPluginState.ClientFusionDatabase.Name, oPluginState.Plugin.Name);
        }

        if (xPlugin == null)
        {
            API.Log.Write("ActivityTrace.ShowXMLLog", "XML for " + oPluginState.ClientFusionDatabase.Name + " was null.");
            XElement NewPlugin = new XElement("Plugin",
                new XAttribute("PluginName", oPluginState.Plugin.Name),
                new XAttribute("Running", "true"),
                new XAttribute("LastStart", DateTime.Now.ToString()),
                new XAttribute("LastSuccess", ""),
                new XAttribute("LastExitStatus",""));

            lock (xDoc)
            {
                var Location = from database in xDoc.Root.Elements("Database")
                               where database.Attribute("DatabaseName").Value == oPluginState.ClientFusionDatabase.Name
                               select database;

                Location.FirstOrDefault().Add(NewPlugin);
                xDoc.Save(XmlLogFilePath);
            }

            oResponse = oPluginState.Plugin.Run(oPluginState.ClientFusionDatabase);
            if (oResponse == null)
            {
                API.Log.Write("ActivityTrace.ShowNullReturnLog", oPluginState.ClientFusionDatabase.Name + "- " + oPluginState.Plugin.Name + " returned null.");
            }

            lock (xDoc)
            {
                NewPlugin.Attribute("Running").Value = "false";
                NewPlugin.Attribute("LastExitStatus").Value = oResponse.ResponseType.ToString();
                if (oResponse.ResponseType == PluginResponseTypes.Success || oResponse.ResponseType == PluginResponseTypes.Warning)
                    NewPlugin.Attribute("LastSuccess").Value = DateTime.Now.ToString();
                xDoc.Save(XmlLogFilePath);
            }

            API.Log.Write("ActivityTrace.ShowXMLLog","Completed " + oPluginState.ClientFusionDatabase.Name + "- " + oPluginState.Plugin.Name + " with XML " + NewPlugin.ToString());
            API.Log.Write(oPluginState.Plugin.Name, "(" + oPluginState.ClientFusionDatabase.Connection.Database + " = " + (oResponse.ResponseType + ") ").PadRight(9) + "EXIT MESSAGE: " + (string.IsNullOrEmpty(oResponse.Message) ? "None" : oResponse.Message));
        }
        else
        {
            DateTime dLastRun = (DateTime)xPlugin.Attribute("LastStart");
            bool bRunning = (bool)xPlugin.Attribute("Running");

            if ((DateTime.Now - dLastRun) > oPluginState.Plugin.Interval && !bRunning)
            {
                lock (xDoc)
                {
                    xPlugin.Attribute("LastStart").Value = DateTime.Now.ToString();
                    xPlugin.Attribute("Running").Value = "true";
                    xDoc.Save(XmlLogFilePath);
                }
                oResponse = oPluginState.Plugin.Run(oPluginState.ClientFusionDatabase);

                lock (xDoc)
                {
                    xPlugin.Attribute("Running").Value = "false";
                    xPlugin.Attribute("LastExitStatus").Value = oResponse.ResponseType.ToString();
                    if (oResponse.ResponseType == PluginResponseTypes.Success || oResponse.ResponseType == PluginResponseTypes.Warning)
                        xPlugin.Attribute("LastSuccess").Value = DateTime.Now.ToString();
                    xDoc.Save(XmlLogFilePath);
                }

                API.Log.Write(oPluginState.Plugin.Name, "(" + oPluginState.ClientFusionDatabase.Connection.Database + " = " + (oResponse.ResponseType + ") ").PadRight(9) + "EXIT MESSAGE: " + (string.IsNullOrEmpty(oResponse.Message) ? "None" : oResponse.Message));
            }
            else if (bRunning)
                API.Log.Write(oPluginState.Plugin.Name, "(" + oPluginState.ClientFusionDatabase.Connection.Database + " = " + ("SKIPPED) ").PadRight(9) + "REASON: Plugin already running");
        }

        oPluginState.Complete = true;
    }

問題是一個或多個插件未正確處理錯誤,這導致它不返回任何響應並使程序崩潰。

要讀取XML文件而不分析整個內容並將其加載到內存中,可以使用XmlReader 然后,要編寫XML文件,可以使用XmlWriter 在相應的MSDN頁面上有一些示例。

但是,您將失去LINQ的所有好處,並且它的工作原理也大不相同。 僅在磁盤上處理XML文件時,實際上沒有辦法結合LINQ和XDocument的優點。

然后,當您的服務崩潰時,您的XmlWriter可能仍然不會被處置,不會將其緩沖區刷新到磁盤上,並留下不完整的XML文件。 您應該解決導致服務崩潰的錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM