У меня есть программа, которая запускает ряд плагинов с использованием потоков. Во время этого процесса он записывает время выполнения плагинов в 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.
Почему мой XDocument сохраняет неполный файл?
Я провел несколько заявлений трассировки и обнаружил, что время до этого, служба не удалось с около 44 плагинов осталось для запуска, что, по-видимому, заставило XDocument закрыться без записи конца файла. Он записывает и читает из файла XML на жестком диске, но выполняет все операции над XDocument в памяти, потому что я использую Linq для выполнения сложных операций с данными.
Кто-нибудь знает, почему это может случиться? Как я могу загрузить свой XDocument, чтобы он не повредил фактический файл, если что-то происходит во время работы?
EDIT: Вот пример кода, который использует 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;
}
Проблема заключается в том, что один или несколько плагинов не обрабатывает ошибки правильно, что приводит к его не вернуть любой ответ и сбой программы.
Невозможно ли разместить какой-либо пример кода и ввода? –
Из вашей истории я понял, что ваш сервис падает? Если это так, вы вряд ли можете ожидать, что все объекты будут удалены правильно и записать их изменения на диск. – Virtlink
Я попытаюсь добавить некоторые. Повесить там. – ijb109