IMMORTAL
IMMORTAL

Reputation: 2857

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

I trying to develop a Windows Forms application for reading and writing a very large XML file. I have two buttons, 1) for writing an XML file, ** and 2) reading an XML file. When I click on the write XML button my winForm application is hanging. No other operation is allowed to be performed while writing to the XML file, but I want to read and write into same XML file.

For reading

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);
    }
}

For writing

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();
    }
 }

Upvotes: 0

Views: 1804

Answers (4)

Sandy
Sandy

Reputation: 11687

Just being out of box... You can also give a try on Xsd2Code. It is a open source tool which even we are using in our project. It's easy to maintain and is managed. Even if we process large XML files.

And regarding Windows Forms being hang, first of all, using XPath may make your operations faster. Regarding hanging, operation in a new thread is the only hope I can see. As when you write an XML file, your main window thread is busy. Skeleton code for threading may be:

private void WriteXML_Click(object sender, EventArgs e)
{
    Thread t = new Thread(new ThreadStart(WriteXMLFile));
    t.Start();
}

private void WriteXMLFile()
{
    // Write an XML file
}

This code is just a sample code for using threads. These posts, posts can also be helpful.

Upvotes: 0

Nikhil D
Nikhil D

Reputation: 2509

Yes, because the method you use to write, XmlNodeListToDataTable(), binds whole xml nodes. You create rows and then add coloumns and then add value to the respective coloumns. Imagine if the file size of the XML file is 1 GB. Then there are plenty of XML nodes, so it takes a lot of time to bind the whole XML data to a datatable.

So a better way get an XML file in a dataset and for display purposes, you could traverse the datatable in a dataset. Specifically, it takes less time compared to binding XML to a datatable..

Upvotes: 0

BeginnerCoder
BeginnerCoder

Reputation: 403

The application is hanging, because it is trying to open up the file. What method are you using in "XmlNodeListToDataTable"? MSXML? If so, try using XPath, it is faster and will load your XML quicker. Also, "XmlNodeListToDataTable" can be done in a separate thread to allow your GUI to be still responsive if you need it.

Upvotes: 0

TomTom
TomTom

Reputation: 62093

The application hangs because you use the UI thread to do all your work, instead of moving it to a separate thread.

This takes time (as operation) and as long as the UI Thread is busy, it can not process important messages for redraw, move, react to mouse etc.

Background Worker, in .NET 4.5 async method for the handler, will fix that in no time.

Upvotes: 2

Related Questions