【发布时间】:2020-08-20 07:00:24
【问题描述】:
我有一个包含 50K 到 100K 字的 List<string>
我想以并行和异步方式迭代它
例如,我可以使用
while (true)
{
Parallel.ForEach(words, new ParallelOptions { MaxDegreeOfParallelism = 100 }, ...)
}
但问题是:
-
Parallel.ForEach不是异步 - 当我们到达列表的末尾时,我们必须等待每个线程结束,然后
while (true)语句才能继续 - 这意味着没有始终运行 100 个线程,这正是我想要的
我怎样才能做到这一点?
如果这令人困惑,或者我不善于解释,请告诉我。
【问题讨论】:
-
您几乎肯定不希望始终运行 100 个线程...
-
1) 为什么要异步?考虑到它在无限循环中,这将是危险的。另外,您不应该将
async/await与Parallel.xxx一起使用 2) 所以 3) 也许,也许不是。Parallel.xxx的动态线程池大小调整非常聪明。您可能需要考虑 TPL DataFlow,因为它支持管道;限制和节流,并且与异步配合得很好。 TPLDF 同时满足 CPU 密集型和 I/O 密集型作业 -
如果您实际上想要同时运行 100 个线程(同样,您真的不希望 - 您一定会感到困惑),那么您将不得不手动使用 Thread 对象。 .Net 中的异步实现将自行处理线程以达到最佳数量,除非您有 128 个核心服务器,否则它不会一次分配 100 个运行。任何时候你使用 await 一个线程池线程都会获得延续,并且很可能不会有 100 个线程池线程
-
"我正在使用 HttpClient" - 那么你肯定不想启动 “100 个线程”。启动一个只是等待 I/O 的线程是对线程的浪费。可悲的是,启动一个只处理一个网络链接的线程更糟糕。
Parallel.xxx与async/await很危险,您希望后者支持 IOCP。最好使用 TPL DataFlow 和async/await。对于这种事情来说,这真是太棒了。Parallel.ForEach最适合用于受 CPU 限制的操作,而您的操作似乎不是 -
这听起来像是一个 X/Y 问题 - 为什么你认为你需要同时 100 个?
标签: c# asynchronous parallel-processing async-await