【发布时间】:2018-08-19 09:57:13
【问题描述】:
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 行输入。
编辑
按照 cmets 中的说明,我从 new Thread(()=>{}).Start(); 更改为 Task.Factory.StartNew(()=>{});,似乎是线程创建和销毁导致性能下降。这似乎是对的。在我移至 Task.Factory.StartNew 后,它的运行速度与信号量提到的相同,它的 CPU 与我的 Parallel.ForEach 代码版本完全相同。
【问题讨论】:
-
这是因为您每次都创建和销毁线程...这会导致巨大的性能损失。
-
@Essigwurst 这不是 Parallel.ForEach 所做的吗?
标签: c# while-loop semaphore filestream streamreader