c#-将1000个XML中的值保存到excel

c#-将1000个XML中的值保存到excel,c#,.net,xml,visual-studio,xpath,C#,.net,Xml,Visual Studio,Xpath,我的C#应用程序循环5000多个文件,然后将XPath的值写入excel工作表中的单元格。每秒处理40个文件相当慢 在分析之后,我发现这一行占所有使用时间的50%以上: XmlDocument.Load(filename); 要写入excel,请在每个文件的每个xpath上循环,并执行以下操作: worksheet.Cells[row, col] = value; 在速度方面,一次将所有XML加载到内存中(每个XML小于20kb),然后将它们存储在一个集合中,然后将它们全部转换到excel是

我的C#应用程序循环5000多个文件,然后将XPath的值写入excel工作表中的单元格。每秒处理40个文件相当慢

在分析之后,我发现这一行占所有使用时间的50%以上:

XmlDocument.Load(filename);
要写入excel,请在每个文件的每个xpath上循环,并执行以下操作:

worksheet.Cells[row, col] = value;
在速度方面,一次将所有XML加载到内存中(每个XML小于20kb),然后将它们存储在一个集合中,然后将它们全部转换到excel是否更有利


我理解多线程可能会降低性能,而不是提高性能,因为进程是IO绑定的。

它可能不是IO绑定的。大部分时间用于构建XMLDOM。但是,多线程可能会带来一个问题,具体取决于将结果写入Excel的位置。我不确定,但如果您只能从单个线程访问Office对象,我也不会感到惊讶

在写入Excel对象之前,您必须添加一个额外的步骤来收集结果。这必须是某种类型的同步收集,或者是另一个线程专用于写入Excel,或者是在处理完所有文件后执行

现在,回到第一点:大部分时间都花在加载DOM上。根据“如果您仍然需要DOM相关方法”的结果,我将转而考虑使用XDocument。该接口与XmlDocument的距离不远,因此它应该是一个易于调整的接口

要获得处理XML的最快速度,请查看XmlReader。但是,这并没有得到任何DOM函数,并且可能比两个基于DOM的方法更难处理

因此,简而言之,首先尝试转换到XDocument方法,这可能会使您的速度提高一倍。然后,我将考虑将处理转换为多线程(可能在文件列表上使用PLINQ)。最后,如果性能仍然不够,请尝试使用XmlReader接口

编辑以响应要使用的集合类型:

我看到了两个基本选项,这取决于处理XML文件所需的时间。如果它只占整个过程的一小部分(大部分时间都花在处理Excel上),只需创建一个
列表
,其中
T
是您需要写入Excel的数据的一些表示形式(如果您只需要它,它甚至可以是一个字符串),并使用
。添加
锁所包围的
方法。然后,一旦XML处理完成,Excel编写器将迭代此集合

另一个选项是,如果XML处理需要一段时间,并且您在.NET4上,请查看
ConcurrentQueue
类。这本身就可以提供线程安全性(我现在看到的是,在第一种情况下也可以使用一个并发集合,
ConcurrentQueue
BlockingCollection
)。然后,您将有线程运行处理XML,然后是写入Excel的消费者线程

其他一些事情。扩展对问题的评论,如果您不做任何需要Excel特定功能的事情,您可以直接将其写入CSV。这里的库使用起来相当简单,可以处理嵌入的逗号。这样做的缺点是,如果您试图保存CSV,excel会弹出可怕的对话框。然而,通过用户培训可以克服这些问题


如果您的目标至少是Excel 2007(尽管Excel 2003可以使用加载项读取xlsx文件),另一个选项是使用生成Excel文件,前提是您尚未这样做。我想,由于这个库处理XML,它将比处理Excel互操作更快,也更安全(没有Excel对话框,没有僵尸进程等)。

它可能不受IO限制。大部分时间用于构建XMLDOM。但是,多线程可能会带来一个问题,具体取决于将结果写入Excel的位置。我不确定,但如果您只能从单个线程访问Office对象,我也不会感到惊讶

在写入Excel对象之前,您必须添加一个额外的步骤来收集结果。这必须是某种类型的同步收集,或者是另一个线程专用于写入Excel,或者是在处理完所有文件后执行

现在,回到第一点:大部分时间都花在加载DOM上。根据“如果您仍然需要DOM相关方法”的结果,我将转而考虑使用XDocument。该接口与XmlDocument的距离不远,因此它应该是一个易于调整的接口

要获得处理XML的最快速度,请查看XmlReader。但是,这并没有得到任何DOM函数,并且可能比两个基于DOM的方法更难处理

因此,简而言之,首先尝试转换到XDocument方法,这可能会使您的速度提高一倍。然后,我将考虑将处理转换为多线程(可能在文件列表上使用PLINQ)。最后,如果性能仍然不够,请尝试使用XmlReader接口

编辑以响应要使用的集合类型:

我看到了两个基本选项,这取决于处理XML文件所需的时间。如果它只占整个过程的一小部分(大部分时间都花在处理Excel上),只需创建一个
列表
,其中
T
是您需要写入Excel的数据的一些表示形式(如果您只需要它,它甚至可以是一个字符串),并使用
。添加
锁所包围的
方法。然后,一旦XML处理完成,Excel编写器将迭代此集合

另一个选项是,如果XML处理需要一段时间,并且您在.NET4上,请查看
ConcurrentQueue
类。这将自己提供线程安全性(我现在看到的是,在第一种情况下也可以使用一个并发集合,
ConcurrentQueue
BlockingCollection