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 行输入。
EDIT
我从new Thread(()=>{}).Start();
to Task.Factory.StartNew(()=>{});
正如评论中提到的,线程的创建和销毁似乎导致了性能下降。这似乎是对的。在我转移到 Task.Factory.StartNew 后,它的运行速度与信号量提到的相同,并且它的 CPU 与我的 Parallel.ForEach 代码版本完全相同。
您的代码创建了大量线程,效率很低。
C# 有更简单的方法来处理您的场景。一种方法是:
File.ReadLines(path, Encoding.UTF8)
.AsParallel().WithDegreeOfParallelism(10)
.ForAll(doSomething);
-
File.ReadLines不读取整个文件,而是逐行读取。
- Use WithDegreeOfParallelism设置并发执行任务的最大数量
- Use ForAll在每一行启动一个方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)