Reputation: 2857
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.
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();
}
}
Upvotes: 0
Views: 1804
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
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
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
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