C# 多线程将xml文件加载到内存中

C# 多线程将xml文件加载到内存中,c#,multithreading,performance,file,C#,Multithreading,Performance,File,我有一组XML文件要加载到内存中以便处理 我正在将文件加载到一个集合中,如果在单个线程中加载文件,而不是使用线程池,那么速度似乎要快得多 我本以为情况会相反 为什么使用多个线程将文件加载到内存中的速度要比在单个线程上迭代文件列表并逐个加载每个文件的速度慢得多 这是C#net 3.5的一部分 守则: ICollection<XmlDocument> xmlFilesToProcess = new Collection<XmlDocument>(); foreach (Fi

我有一组XML文件要加载到内存中以便处理

我正在将文件加载到一个集合中,如果在单个线程中加载文件,而不是使用线程池,那么速度似乎要快得多

我本以为情况会相反

为什么使用多个线程将文件加载到内存中的速度要比在单个线程上迭代文件列表并逐个加载每个文件的速度慢得多

这是C#net 3.5的一部分

守则:

ICollection<XmlDocument> xmlFilesToProcess = new Collection<XmlDocument>();

foreach (FileInfo fileInfo in fileList)
{
     ThreadPool.QueueUserWorkItem(
        (o) =>
        {
            XmlDocument doc = new XmlDocument();
            doc.Load((string)o);
            lock (xmlFilesToProcess)
            {
                xmlFilesToProcess.Add(doc);
                counter++;
            }
        }, fileInfo.FullName);
}
ICollection xmlFilesToProcess=new Collection();
foreach(文件列表中的FileInfo FileInfo)
{
ThreadPool.QueueUserWorkItem(
(o) =>
{
XmlDocument doc=新的XmlDocument();
单据加载((字符串)o);
锁(xmlFilesToProcess)
{
xmlFilesToProcess.Add(doc);
计数器++;
}
},fileInfo.FullName);
}

如果没有看到代码,我想这可能与从磁盘读取是操作的缓慢部分这一事实有关。由于磁盘一次只能读取一个文件,因此磁盘成为瓶颈。

如果看不到代码,就很难说了。如果XML的大小和/或数量很小,并且您只有一个CPU,那么很可能是线程之间的上下文切换花费的时间比读取文件所需的时间要多

编辑

现在我看到了您正在创建的代码太多线程了。我建议你使用平行的。对于第三方物流。这适用于.Net 3.5


有关TPL的更多信息,请参阅。

每当您需要决定多线程还是单线程时,最好在运行应用程序的机器上进行基准测试

由于线程同步上的额外开销,多线程代码可能会更慢。即使使用ThreadPool,也会有线程创建的初始开销

在不知道要解决的问题的细节的情况下,很难提出什么是单线程或多线程更好


此外,很难在看不到代码的情况下说明为什么一个代码比另一个代码慢。

xml文件相对较小(在10k-500k之间),但它们的数量很大(>10000),您创建的线程太多了。创建线程/上下文切换所花费的时间比实际的XML处理所花费的时间要多。是否并行。是否不在内部使用线程池?我的理解是ThreadPool.QueueUserWorkItem实际上并不创建另一个线程,它只是创建一个将由ThreadPool处理的项目。运行时决定线程池中有多少线程可用。实际上,TPL似乎在内部使用线程池,因此我认为并行。For在性能方面与QueueUserWorkItem有任何不同。看有趣的。我使用线程池是因为我认为它没有创建大量线程?无论哪种方式,瓶颈都在于从单个磁盘并行读取文件。在这一点上,我只是想尽可能快地将文件加载到内存中,由于我缺乏磁盘I/O方面的知识,我错误地认为多线程会更快。出于某种原因,我一直认为TPL只是一个.net4的东西,所以我肯定会研究我正在做的其他线程。我用代码进行了更新,我想在这种情况下使用线程是没有实际意义的,因为我一次只能从磁盘读取一个文件?我想这是可能的。您可以通过将所有文件预加载到内存中,然后将它们加载为单线程而不是线程池来进行测试。这将使从磁盘读取的数据从方程中消失。当然,也可能是其他事情。正如其他答案所陈述的,如果你只有1个处理器的多线程,那就没什么帮助了。如果你考虑并行解析,这是有意义的,但是这当然会减轻并行读取对IO系统的影响。收益可能微不足道@rsbarro,可以使用1个IO线程对缓冲区和并行解析器进行排队。@rsbarro,我尝试过这个,线程池花费的时间几乎是原来的两倍。我有一个4核的i5。我正在加载11534个文件,大多数文件的大小都在10kb左右。@dvhh在我的评论中,我试图找到一种方法来确定磁盘是否是瓶颈,但是,是的,我认为使用单IO线程是一种很好的方法。