XDocument 到 DataTable 异步

费雪8370

我正在将 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
        );
    }
}
YK1

然而,这个问题绝对没有唯一的答案。您可以通过多种方式做到这一点,这是一种:

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章