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

2023-12-06

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

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(使用前将#替换为@)

C# - 使用 StreamReader 并行化 While 循环会导致 CPU 过高 的相关文章

随机推荐

  • 如何将 std::variant 的元素复制到另一个变体类型的变量

    这是后续这个答案 假设我们有两种类型std variant具有部分相同的成员类型 例如如果我们有 struct Monday struct Tuesday etc using WeekDay std variant
  • Snakemake - 下载数据的规则

    我在实现管道时遇到一些麻烦 其中第一步是从某个服务器下载数据 据我了解 所有规则都必须有文件输入 然而 在我的例子中 输入 是提供给访问服务器并下载数据的脚本的 ID 字符串 我知道远程文件Snakemake 中的选项 但我正在下载的服务器
  • 在同一场景上加载多个视频时 Unity 应用程序冻结

    从菜单导航到包含 8 个 1 分钟 MP4 视频的场景时 这些视频在 RawImage 组件上使用新的 VideoPlayer 脚本进行播放 我使用的是Unity 5 6 0b11测试版 在我尝试导航的场景中 预制件会在列表缩略图中加载视频
  • 保护 NodeJS 的 post 路由

    我正在开发一个 NodeJS 应用程序 到目前为止 我了解到您可以使用 JWT 保护路由 并且我已经实现了这一点 问题是 我不确定如何保护允许用户发帖的路由 我们以注册路由为例 该路由将用于用户注册 我希望用户能够发布此内容 但只能从我的应
  • Excel:使用 vba 添加评论作者

    当我手动向单元格添加注释 使用插入注释命令 时 文本前面会以粗体显示我的用户名 是否可以为创建的评论复制此特征vba using Range AddComment 对于运行宏的用户 您可以添加登录的用户名 用户名以粗体显示 如下所示 此示例
  • 如何让Flask跨两台不同的机器与Flask通信?

    我在一台机器上有一个 Flask 应用程序 在第二台机器上需要运行一些查询 第二台机器不渲染任何页面 它只是在第一个应用程序的幕后做一些事情 如果我在第二台计算机上创建 Flask 应用程序来控制这些查询 我如何从第一个应用程序与其进行通信
  • JS > FTP > 网页目录 > 文件列表

    是否可以使用 Javascript 调用对指定 URL 的 FTP 调用并检索此 Web 目录中的所有文件 假设您正在讨论浏览器中的 javascript 那么如果没有一些支持的服务器端代码 这是不可能的 您可以使用 javascript
  • 在 Windows 任务计划程序中更改已计划任务的运行时间

    我在修改机器上已存在的任务时遇到问题 我正在尝试使用 C 生成的互操作接口 从 system32 taskschd dll 生成的 Interop TaskScheduler dll 来执行此操作 首先 我无法使用其他库 例如http ta
  • Java try-finally返回设计问题

    在 Java 中 try finally 的执行对我来说有点不直观 正如另一个问题中所说明的 Java中finally总是执行吗 如果try块中有return语句 如果定义了finally块 它将被忽略 例如 函数 boolean test
  • Android:如何在应用程序中集成admob?

    我试图将 admob 横幅集成到我的应用程序中几个小时 但我做不到 所以我创建了新的应用程序 其唯一目的是显示 admob 横幅 但它也不起作用 这是代码 public class MainActivity extends Activity
  • 如何以编程方式从 Windows 手机访问 SMS 消息线程 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我想访问 Windows Phone 上的所有消息并备份它或在 PC 手机上复制它 我搜索了这个 但无法在互联网上找到它 有没有可用的 API 来实现这一点 这仅适用于 Wind
  • Breezejs 与保存包有关的问题

    我使用breezejs 我的应用程序的服务器端代码是 net 在我看来 客户端 我想添加实体 然后我想保存它 让我们假设一个实体是这样的 Id 1 Name someName CreatedDate 1900 01 01T05 00 00Z
  • TreeView 重新获得 Ctrl+Click 的焦点

    我有一个 WinForms TreeView 控件 我想用它来根据当前选择的节点打开另一个窗体 我想在按住 Ctrl 键并单击节点时打开另一个窗体 目前 如果我在 DoubleClick 处理程序中打开另一个表单 显然是双击该节点 它就会按
  • 应用速率大于 2 倍时,avplayer 播放时出现抖动

    我想调整 Avplayer 速率 我可以在以下帮助下完成 avplayer play avplayer setRate 1 5 还禁用了音轨 低于2 0时运行良好 但当我们应用它超过 2 倍时 就会导致视频不稳定或不稳定 当我用谷歌搜索这一
  • 如何在 OpenEdge SQL 中模拟 SELECT ... LIMIT、OFFSET?

    在大多数 SQL 实现中 能够选择查询中返回的所有行的 滑动窗口 子集是很常见的事情 一个常见的用例是分页 例如 假设我有一个搜索页面 每页有 10 个结果 对于支持的实现LIMIT and OFFSET关键字 用于返回每个页面结果的查询如
  • IE8 不透明度问题

    我尝试解决IE8中出现的问题 Html 非常简单 div div div div div div div div 当我在 IE 中设置 使用 jQuery source 元素的不透明度为 0 时 我可以看到 overlay 的背景 而不是
  • 有没有办法查询未来的SSRS订阅时间表?

    在我的办公室 我们中的许多人都使用 SSRS 来安排定期报告 我想查看接下来几天或一周内即将运行的报表的时间表 以便我们可以了解 20 个报表是否都将尝试同时运行 我怎样才能做到这一点 我创建了显示订阅信息的 t sql 报告 但它们仅显示
  • 从 javascript 中的对象数组中删除重复值[重复]

    这个问题在这里已经有答案了 我有一个像这样的对象数组 arr label Alex value Ninja label Bill value Op label Cill value iopop 该数组是在渲染我的反应组件时组成的 第 i 个
  • 如何在代码中为树视图设置 WPF 数据模板?

    struct Drink public string Name get private set public int Popularity get private set public Drink string name int popul
  • C# - 使用 StreamReader 并行化 While 循环会导致 CPU 过高

    SemaphoreSlim sm new SemaphoreSlim 10 using FileStream fileStream File OpenRead using StreamReader streamReader new Stre