Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Parallel.ForEach/多线程的最佳使用_C#_.net_Multithreading_Parallel.foreach - Fatal编程技术网

C# Parallel.ForEach/多线程的最佳使用

C# Parallel.ForEach/多线程的最佳使用,c#,.net,multithreading,parallel.foreach,C#,.net,Multithreading,Parallel.foreach,我需要从网站上搜集数据。 我需要访问1000多个链接,之前我将每个线程划分10个链接,然后开始100个线程,每个线程10个。在几个测试用例之后,100个线程是减少检索所有链接内容的时间的最佳计数 我意识到.NET4.0提供了更好的对开箱即用多线程的支持,但这是根据您拥有多少内核来完成的,在我的例子中,这并没有产生足够的线程。我想我要问的是:优化1000链接拉取的最佳方法是什么。我应该使用.ForEach并让并行扩展控制生成的线程数量,还是想办法告诉它要启动多少线程并分配工作 我以前没有使用过Pa

我需要从网站上搜集数据。 我需要访问1000多个链接,之前我将每个线程划分10个链接,然后开始100个线程,每个线程10个。在几个测试用例之后,100个线程是减少检索所有链接内容的时间的最佳计数

我意识到.NET4.0提供了更好的对开箱即用多线程的支持,但这是根据您拥有多少内核来完成的,在我的例子中,这并没有产生足够的线程。我想我要问的是:优化1000链接拉取的最佳方法是什么。我应该使用
.ForEach
并让
并行
扩展控制生成的线程数量,还是想办法告诉它要启动多少线程并分配工作


我以前没有使用过
Parallel
,所以我的方法可能是错误的。

一般来说,
Parallel.ForEach()
非常擅长优化线程数量。它考虑了系统中的内核数量,但也考虑了线程正在做什么(CPU限制、IO限制、方法运行的时间等)

您可以控制并行化的最大程度,但没有强制使用更多线程的机制


确保您的基准测试是正确的,并且能够以公平的方式进行比较(例如,相同的网站,在开始测量之前留出一段预热期,并且进行多次运行,因为响应时间差异可能会相当大)。如果经过仔细测量,您自己的线程代码仍然更快,您可以得出结论,您针对特定情况进行了优化,优于.NET,并坚持使用您自己的代码。

如果不查看您的代码以及集合的定义,很难说,
Parallel.Invoke
是最灵活的。尝试听起来你想使用
Parallel.For方法(Int32,Int32,Action)

值得一看的是TPL数据流库

在MSDN上

Parallel.ForEach()背后的全部思想是,您有一组线程,每个线程处理集合的一部分。正如您所注意到的,这不适用于async Wait,您希望在异步调用期间释放线程

此外,演练还专门设置和处理多个网页下载。TPL数据流确实是为这种情况而设计的。

您可以在Parallel.ForEach中使用属性来控制将生成的线程数

下面是代码片段-

ParallelOptions opt = new ParallelOptions();
opt.MaxDegreeOfParallelism = 5;

Parallel.ForEach(Directory.GetDirectories(Constants.RootFolder), opt, MyMethod);

从web上提取链接不是一项CPU限制的任务,因此添加大量线程可能对您没有多大帮助。此外,在大多数当前硬件上产生100个线程是个坏主意。请看一看异步。@BrianRasmussen:对于大量绑定网络IO的任务,这不一定是真的。只要线程池没有耗尽,允许更多并发请求可能是一件好事。如果有100个线程,平均响应时间为1秒,那么单核系统每秒最多只能切换100个上下文,四核系统最多只能切换25个上下文。当然,这些都是假设的数字,但看起来OP已经尝试了各种参数,并确定了最适合其用例和硬件的参数。@EricJ。这就是为什么我说“可能”。无论如何,在启动100个线程之前,我仍然会使用异步解决方案。@BrianRasmussen:async将是一个非常好的选择。也许会发布另一个答案?@BrianRasmussen是的,但如果你不关心浪费的100 MB内存,也不能使用C#5.0,那么创建100个线程比异步执行要好得多。这是一个好模式。我从链接的答案中添加了一个摘要,这样你的答案本身就更好了。也有,但是IMO数据流非常适合这个问题+1.请注意,这只控制线程的最大数量-如果系统决定使用更少的线程,那么它仍然能够使用更少的线程
MaxDegreesOfParallelism
不是保证,只是一个上限。如果不在此处设置值,则默认值基于内核数、系统负载等。