【问题标题】:Async/Await vs Parellel.For, which is better in this instance?Async/Await 与 Parallel.For,在这种情况下哪个更好?
【发布时间】:2017-12-19 02:52:55
【问题描述】:

所以我有 1000 多个项目来检查它们是否是最新的。这些项目中的每一项都需要读取数千个文件(其中一些可能是跨不同项目的相同文件)。

目前这是使用 TPL (async/await) 实现的,一个用于它必须读取的每个文件,一个用于它必须检查的每个项目。这很好用,除了当我分析它时,第三个最昂贵的函数是线程池中的 TrySteal。

使用 Visual Studio 并发查看器,我看到 99% 的线程时间花在并发相关的项目上,而只有 1% 的时间花在执行上。正是这一点让我认为我可能只是创建了太多任务(注意:我不在任何地方使用 Task.Run,​​只是等待)。

与使用 async/await 读取一堆文件相比,Parellel.For 的开销会更少吗?使用任务编程库预计会有多少开销?

【问题讨论】:

  • 您是否检查过资源监视器(可通过 Windows 任务管理器的“性能”选项卡获得)以查看您是否达到了磁盘子系统的性能能力?如果是这样,您可能需要重新考虑问题。缓存数据、使用多个驱动器、使用适当的 RAID 集、SSD、...。
  • 可能两者都不是。相反,您可能需要考虑 TPL DataFlow,因为您可以以适合 I/O 操作次数的方式限制每个块中的消息
  • 我有四个硬件突袭 SSD,因为 90% 的文件已经在内存中,所以磁盘几乎没有滴答作响。但是,所有程序同时运行时,cpu 使用率为 100%,因此我试图通过减少 cpu 使用来进行优化。看来任务调度程序是其中的重要组成部分。

标签: c# .net multithreading asynchronous


【解决方案1】:

如果您正在检查硬盘驱动器上的文件,我认为这个任务的并行性不是很好。如果你试图同时读取数千个文件,你只会让这个过程慢得多,因为它不能同时读取那么多文件,更糟糕的是,它不能将太多文件缓存到内存中。 最快的选项,没有优化检查过程本身,应该只是连续运行它。 如果你真的想优化它,我建议循环遍历文件,检查每个项目,而不是循环遍历项目,检查每个文件。在这种情况下,即使在多个线程中执行(虽然不是一次全部执行)也可能有效。

更新: 如果您有足够的内存来缓存所有文件,那么它不会限制多线程。尽管如此,我还是建议将并行线程的数量限制为数量,与您要使用的处理器内核数量相当。最好用 Parallel.ForEach() 来做。此外,Parallel.Foreach() 明确指出,您的循环是异步的,因此代码会更容易理解。

【讨论】:

  • 在这种情况下,大多数文件都适合内存(并且它们很可能已经在内存中)。即使文件在内存中,同样的建议是否适用?在内存中,我的意思是它们可能在备用列表中,因为它们刚刚被之前的进程使用过。
  • @user2460953 不,我的建议不适用。我更新了我的答案。
  • 由于我有多个项目可能希望在同一个文件中读取,我假设我应该只是在代表文件的对象上的并行 for 循环中进行锁定,对吗?这样,如果两个项目想要对同一个文件进行哈希处理,一个获胜,另一个在锁定解决后看到它已经被哈希处理。
  • @user2460953 很难判断它是否对您的情况有效。但是,如果您对每个文件执行相同的任务,为什么不制作完整的文件列表,然后处理它们(在一个或多个线程中) - 它可能会显着简化逻辑并让您更容易优化流程。
猜你喜欢
  • 1970-01-01
  • 2019-12-04
  • 2013-04-17
  • 2016-12-24
  • 2020-03-15
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 2017-11-04
相关资源
最近更新 更多