我正在将 100-500 个 XML 文件中的数据加载DataTable
到一个 Infragistics UltraGrid 中。这些文件小至 100K,大至 2MB。我一直在寻找加快加载时间并考虑异步的方法,但数据表不是线程安全的。
看过程,加载xdoc大约需要2/3的时间,另外1/3是在读取xdoc和往表中添加数据。
有没有办法使用异步并以某种方式加载下一个,XDocument
而前一个被读取并加载到数据表中?我已经看过了,但我没有看到一个很好的方法来做到这一点。我还应该考虑其他一些策略吗?
这是我正在做的事情的简化版本:
private void openXMLs(){
OpenFileDialog openFileDialog1 = new OpenFileDialog
{
Title = "Browse XML files",
CheckFileExists = true,
CheckPathExists = true,
DefaultExt = "xml",
Filter = @"XML files (*.xml)|*.xml",
FilterIndex = 2,
RestoreDirectory = true,
ReadOnlyChecked = true,
ShowReadOnly = true,
Multiselect = true
};
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
foreach (String file in openFileDialog1.FileNames)
{
XDocument xdoc = XDocument.Load(file)
loadData(xdoc)
}
}
}
private void loadData(XDocument xdoc){
var query = xdoc.Descendants("root").AsEnumerable()
.Select(c => new
{
id = c.Element("ID").Value,
firstname = c.Element("firstname").Value,
lastname = c.Element("lastname").Value,
state = c.Element("state").Value,
});
foreach (var item in query)
{
_dt.Rows.Add(
item.id,
item.firstname,
item.lastname,
item.state
);
}
}
然而,这个问题绝对没有唯一的答案。您可以通过多种方式做到这一点,这是一种:
private async Task openXMLs() {
// .. dialog ..
var loadTasks = new List<Task>();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
foreach (String file in openFileDialog1.FileNames)
{
var xmlFile = XmlReader.Create(file);
XDocument xdoc = await XDocument.LoadAsync(xmlFile, LoadOptions.None, CancellationToken.None);
loadTasks.Add(Task.Run(() => loadData(xdoc));
}
}
await Task.WhenAll(loadTasks);
}
但是,数据表不是线程安全的,您需要锁定对它的访问。这也不能保证添加文档的顺序。
private void loadData(XDocument xdoc){
var query = xdoc.Descendants("root").AsEnumerable()
.Select(c => new
{
id = c.Element("ID").Value,
firstname = c.Element("firstname").Value,
lastname = c.Element("lastname").Value,
state = c.Element("state").Value,
});
lock(_dt) {
foreach (var item in query)
{
_dt.Rows.Add(
item.id,
item.firstname,
item.lastname,
item.state
);
}
}
}
这将在下一个从磁盘读取时加载当前文档。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句