SemaphoreSlim sm = new SemaphoreSlim(10);
using (FileStream fileStream = File.OpenRead("..."))
using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8, true, 4096))
{
String line;
while ((line = streamReader.ReadLine()) != null)
{
sm.Wait();
new Thread(() =>
{
doSomething(line);
sm.Release();
}).Start();
}
}
MessageBox.Show("This should only show once doSomething() has done its LAST line.");
所以,我有一个非常大的文件,我想在每一行上执行代码。
我想并行执行,但一次最多 10 个。
我的解决方案是使用 SemaphoreSlim 在线程完成时等待并释放。 (由于函数是同步的,所以 .Release() 的放置是有效的)。
问题是代码占用大量 CPU。内存按预期运行,而不是加载超过 400mb,它只是每隔几秒就会上下几mb。
但是 CPU 变得疯狂,它的大部分时间都锁定在 100% 上长达 30 秒,然后稍微下降并返回。
由于我不想将每一行都加载到内存中,并且想要运行代码,所以这里最好的解决方案是什么?
9,700 行文件中的 500 行输入。
270 万行文件中的 600 行输入。
编辑
我从 new Thread(()=>{}).Start();
改为 Task.Factory.StartNew(()=>{});
正如评论中提到的,线程创建和销毁似乎导致性能下降。这似乎是对的。在我移至 Task.Factory.StartNew 后,它的运行速度与 Semaphore 中提到的相同,它的 CPU 与我的 Parallel.ForEach 代码版本完全相同。
最佳答案
您的代码创建了大量线程,效率低下。 C# 有更简单的方法来处理您的场景。一种方法是:
File.ReadLines(path, Encoding.UTF8)
.AsParallel().WithDegreeOfParallelism(10)
.ForAll(doSomething);
-
File.ReadLines
不读取整个文件,而是逐行读取。 - 使用
WithDegreeOfParallelism
设置并发执行任务的最大数量 - 使用
ForAll
在每一行开始一个方法。
关于C# - 使用 StreamReader 并行化 While 循环导致高 CPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49217299/