用于读取和写入非常大的XML文件的Windows窗体应用程序,但它正在挂起
本文关键字:应用程序 窗体 挂起 Windows 文件 读取 非常 XML 用于 | 更新日期: 2023-09-27 17:55:46
我试图开发一个用于读取和写入非常大的XML文件的Windows窗体应用程序。我有两个按钮,1)用于编写XML文件,**和2)读取XML文件。当我单击写入XML按钮时,我的winForm应用程序正在挂起。写入 XML 文件时不允许执行其他操作,但我想读取和写入同一个 XML 文件。
供阅读
void btnReading_Click(object sender, EventArgs e)
{
strXpathQuery = "/AppXmlLogWritter/LogData[substring(LogDateTime, 1, 8) >='" +
dateTimePickerFromDate.Value.ToString("yyyyMMdd") +
"' and substring(LogDateTime, 1, 8) <='" +
dateTimePickerToDate.Value.ToString("yyyyMMdd") +
"']";
XmlElement objXmlRoot = null;
XmlNodeList objxmlNodeList = objXmlRoot.SelectNodes(strXpathQuery);
}
void BindData(objxmlNodeList);
{
BindData(XmlNodeList objxmlNodeList)
DataTable dataTable = new DataTable();
dataTable = XmlNodeListToDataTable(objxmlNodeList, new string[] { "LogID", "LogDateTime"});
lstViewInfo.View = View.Details;
lstViewInfo.Clear();
lstViewInfo.Columns.Add("LogID", Convert.ToInt32(lstViewInfo.Width * 0.20));
lstViewInfo.Columns.Add("LogDateTime", Convert.ToInt32(lstViewInfo.Width * 0.20));
ListViewItem objListViewitem = null;
for (int i = 0; i < dataTable.Rows.Count; i++)
{
objListViewitem = new ListViewItem();
objListViewitem.Text = dataTable.Rows[i]["LogID"].ToString();
objListViewitem.SubItems.Add(dataTable.Rows[i]["LogDateTime"].ToString());
lstViewInfo.Items.Add(objListViewitem);
}
}
用于写作
void button1_Click(object sender, EventArgs e)
{
Mutex objMutex = new Mutex(false, @"Global'MySharedLog");
XmlDocument xmlDoc = new XmlDocument();
string currentDateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
XmlElement newelement = xmlDoc.CreateElement("LogData");
XmlElement xmlLogID = xmlDoc.CreateElement("LogID");
XmlElement xmlLogDateTime = xmlDoc.CreateElement("LogDateTime");
int randomNumber = random.Next(9999);
xmlLogID.InnerText = _logIDPrefix + currentDateTime + DateTime.UtcNow.Ticks + randomNumber;
xmlLogDateTime.InnerText = currentDateTime;
newelement.AppendChild(xmlLogID);
newelement.AppendChild(xmlLogDateTime);
try
{
objMutex.WaitOne();
if (!File.Exists(_logFilePath))
{
File.WriteAllText(
_logFilePath,
"<?xml version='1.0' encoding='utf-8' standalone='yes'?>'r'n<AppXmlLogWritter><objMutex></objMutex></AppXmlLogWritter>");
}
using (FileStream fileStream = new FileStream(_logFilePath,
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.ReadWrite))
{
xmlDoc.Load(fileStream);
xmlDoc.DocumentElement.AppendChild(newelement);
fileStream.SetLength(0);
xmlDoc.Save(fileStream);
}
}
finally
{
objMutex.ReleaseMutex();
}
}
应用程序挂起是因为您使用 UI 线程执行所有工作,而不是将其移动到单独的线程。
这需要时间(作为操作),只要 UI 线程繁忙,它就无法处理重绘、移动、响应鼠标等重要消息。
处理程序的 .NET 4.5 异步方法中的后台辅助角色将立即修复此问题。
应用程序挂起,因为它正在尝试打开文件。您在"XmlNodeListToDataTable"中使用什么方法?MSXML?如果是这样,请尝试使用 XPath,它更快,并且加载 XML 的速度更快。此外,"XmlNodeListToDataTable"可以在单独的线程中完成,以便在需要时允许GUI仍然响应。
是的,因为您用来编写的方法 XmlNodeListToDataTable() 绑定了整个 xml 节点。创建行,然后添加列,然后向相应的列添加值。想象一下,如果 XML 文件的文件大小为 1 GB。然后有大量的 XML 节点,因此将整个 XML 数据绑定到数据表需要花费大量时间。
因此,在数据集中获取 XML 文件并出于显示目的的更好方法,您可以在数据集中遍历数据表。具体来说,与将 XML 绑定到数据表相比,它花费的时间更少。
只是开箱即用...您也可以尝试Xsd2Code。它是一个开源工具,甚至我们在项目中使用的工具。它易于维护和管理。即使我们处理大型XML文件。
关于Windows窗体挂起,首先,使用XPath可能会使您的操作更快。关于挂起,在新线程中操作是我能看到的唯一希望。与编写 XML 文件一样,主窗口线程繁忙。线程的框架代码可能是:
private void WriteXML_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(WriteXMLFile));
t.Start();
}
private void WriteXMLFile()
{
// Write an XML file
}
此代码只是使用线程的示例代码。这些帖子,帖子也会有所帮助。