簡體   English   中英

Windows Forms應用程序用於讀取和寫入非常大的XML文件,但它是懸掛的

[英]Windows Forms application for reading and writing a very large XML file, but it is is hanging

我試圖開發一個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();
    }
 }

應用程序掛起是因為您使用UI線程完成所有工作,而不是將其移動到單獨的線程。

這需要時間(作為操作)並且只要UI線程忙,它就不能處理重要的消息以重繪,移動,對鼠標做出反應等。

后台工作者,在處理程序的.NET 4.5異步方法中,將立即修復它。

該應用程序正在掛起,因為它正在嘗試打開該文件。 你在“XmlNodeListToDataTable”中使用了什么方法? MSXML? 如果是這樣,嘗試使用XPath ,它更快,並將更快地加載您的XML。 此外,“XmlNodeListToDataTable”可以在單獨的線程中完成,以允許GUI在需要時仍然響應。

是的,因為您用來編寫的方法XmlNodeListToDataTable()綁定整個xml節點。 您創建行,然后添加coloumns,然后將值添加到相應的coloumns。 想象一下,如果XML文件的文件大小是1 GB。 然后有大量的XML節點,因此將整個XML數據綁定到數據表需要花費大量的時間。

因此,更好的方法是在數據集中獲取XML文件並顯示,您可以遍歷數據集中的數據表。 具體來說,與將XML綁定到數據表相比,它花費的時間更少。

只是開箱即用......你也可以嘗試一下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
}

此代碼只是使用線程的示例代碼。 這些帖子帖子也可以提供幫助。

暫無
暫無

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

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