0

我试图开发一个Windows 窗体应用程序来读取和写入一个非常大的 XML 文件。我有两个按钮,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();
    }
 }
4

4 回答 4

2

应用程序挂起是因为您使用 UI 线程来完成所有工作,而不是将其移至单独的线程。

这需要时间(作为操作),只要 UI 线程很忙,它就无法处理重绘、移动、对鼠标做出反应等重要消息。

后台工作程序,在处理程序的 .NET 4.5 异步方法中,将立即修复该问题。

于 2013-01-25T06:29:44.183 回答
0

开箱即用...您也可以尝试Xsd2Code。它是一个开源工具,甚至我们在我们的项目中都在使用它。它易于维护和管理。即使我们处理大型 XML 文件。

而关于 Windows Forms 挂起,首先,使用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
}

此代码只是使用线程的示例代码。这些帖子帖子也可以提供帮助。

于 2013-01-25T07:27:34.317 回答
0

应用程序挂起,因为它正在尝试打开文件。您在“XmlNodeListToDataTable”中使用什么方法?MSXML?如果是这样,请尝试使用XPath,它会更快,并且会更快地加载您的 XML。此外,“XmlNodeListToDataTable”可以在单独的线程中完成,以使您的 GUI 在需要时仍能响应。

于 2013-01-25T06:15:27.450 回答
0

是的,因为您用来编写的方法 XmlNodeListToDataTable() 绑定了整个xml节点。您创建行,然后添加列,然后将值添加到相应的列。想象一下,如果 XML 文件的文件大小为 1 GB。然后有大量的 XML 节点,因此将整个 XML 数据绑定到数据表需要花费大量时间。

因此,更好的方法是在数据集中获取 XML 文件并出于显示目的,您可以遍历数据集中的数据表。具体来说,与将 XML 绑定到数据表相比,它花费的时间更少。

于 2013-01-25T06:51:44.527 回答