首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Parallel.ForEachAsync的实际最大并发任务

Parallel.ForEachAsync的实际最大并发任务
EN

Stack Overflow用户
提问于 2022-05-31 12:40:53
回答 2查看 214关注 0票数 1

我希望这段代码需要1秒的时间来执行:

代码语言:javascript
复制
public async void Test()
{
    DateTime start = DateTime.Now;
    await Parallel.ForEachAsync(new int[1000], new ParallelOptions { MaxDegreeOfParallelism = 1000 }, async (i, token) =>
    {
        Thread.Sleep(1000);
    });
    Console.WriteLine("End program: " + (DateTime.Now - start).Seconds + " seconds elapsed.");
}

相反,在我的电脑上需要37秒钟(i7-9700 8核8线程):

代码语言:javascript
复制
End program: 37 seconds elapsed.

我正在用MaxDegreeOfParallelism = 1000....why生成1000个任务,它们不是都同时运行吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-31 13:42:17

Parallel.ForEachAsync方法在ThreadPool线程上调用异步body委托。通常,此委托会快速返回一个ValueTask,但在您的情况下,情况并非如此,因为您的委托并不是真正异步的:

代码语言:javascript
复制
async (i, token) => Thread.Sleep(1000);

您可能收到了编译器的警告,关于缺少async操作符的await方法。不过,给Parallel.ForEachAsync方法提供一个混合的同步/异步工作负载是可以的。此方法设计用于处理任何类型的工作负载。但是,如果工作负载大部分是同步的,则结果可能是饱和的ThreadPool

如果ThreadPool已经创建了由SetMinThreads方法指定的线程数(默认情况下等于Environment.ProcessorCount ),并且需要完成更多的工作,那么它就是饱和的。在这种情况下,ThreadPool切换到一个保守的算法,它每秒钟创建一个新线程(从.NET 6开始)。这种行为并没有被精确地记录下来,而且可能会在未来的.NET版本中发生变化。

为了获得所需的行为,即并行运行所有1000个输入的委托,您必须根据需要立即增加ThreadPool创建的线程数:

代码语言:javascript
复制
ThreadPool.SetMinThreads(1000, 1000); // At the start of the program

有人会说,这样做之后,就不再有线程池了,因为线程池意味着是一个由可重用线程组成的小池。但是,如果您不关心语义,只想完成任务,不管memory consumption和操作系统级的开销会带来什么后果,这是解决问题的最简单方法。

票数 2
EN

Stack Overflow用户

发布于 2022-05-31 12:56:10

我不知道ForEachAsync的确切实现,但我假设它们使用的是Tasks,而不是Threads。

当您使用1000个Tasks来运行1000个CPU绑定操作时,您实际上并不是在创建1000个Threads,您只是要求少数几个ThreadPool Threads来运行这些操作。这些ThreadSleep调用阻塞,所以大多数Task在开始执行之前都会排队。

这就是为什么在Thread.Sleep或者异步上下文中调用Task是一个可怕的想法。如果编辑代码以异步方式而不是同步方式等待,所花费的时间可能更接近一秒钟。

代码语言:javascript
复制
await Parallel.ForEachAsync(new int[1000], new ParallelOptions { MaxDegreeOfParallelism = 1000 }, async (i, token) =>
{
    await Task.Delay(1000);
});
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72447990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档