C# - 使用 StreamReader 并行化 While 循环导致高 CPU

标签 c# while-loop semaphore filestream streamreader

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 行输入。

enter image description here

270 万行文件中的 600 行输入。

enter image description here

编辑

我从 new Thread(()=>{}).Start(); 改为 Task.Factory.StartNew(()=>{});正如评论中提到的,线程创建和销毁似乎导致性能下降。这似乎是对的。在我移至 Task.Factory.StartNew 后,它的运行速度与 Semaphore 中提到的相同,它的 CPU 与我的 Parallel.ForEach 代码版本完全相同。

最佳答案

您的代码创建了大量线程,效率低下。 C# 有更简单的方法来处理您的场景。一种方法是:

File.ReadLines(path, Encoding.UTF8)
    .AsParallel().WithDegreeOfParallelism(10)
    .ForAll(doSomething);

关于C# - 使用 StreamReader 并行化 While 循环导致高 CPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49217299/

相关文章:

c# - 不安全代码对安全代码有影响吗?

c# - Wpf 文本选取框位于其他元素后面

sql - 我可以在 WHILE 循环中使用 CASE 语句吗?

c - 是否允许在 POSIX 中复制未命名的信号量?

c# - Yield 方法中的垃圾收集

Java - 在 Switch Case 中调用另一个输入方法

java 彩票号码

java - 使用信号量的死锁

c - 信号量只能被一个进程获取

c# - 处理程序覆盖 CancelEventArgs 上的 Cancel 属性