我最近发现了以下代码,可以有效地运行大量的IO绑定任务(参见链接)。 http://blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx
我认为以下情况属实:
我的问题是,由于Parallel.ForEach本身有自己的MaxDegreeOfParallelism,我如何知道在IEnumerable扩展的示例代码中定义dop参数的内容?
e.g。如果我要处理1000个项目并且需要为每个项目执行基于IO的SQL-Server数据库调用,我是否将1000指定为 dop ?使用Parallel.ForEach,它被用作限制器,以防止过多的线程旋转,这可能会损害性能。但在这里它似乎用于分区最小数量的异步任务。我认为应该至少没有最大值(最小值是要处理的总项数),因为我想尽可能多地对数据库进行基于IO的调用。
我如何知道如何查看DOP参数?
public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate {
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}));
}
答案 0 :(得分:3)
Parallel.ForEach本身就有自己的MaxDegreeOfParallelism
好吧,Parallel.ForEach
内置的启发式方法很容易随着时间的推移产生大量的任务(如果你的工作项目延迟10毫秒,你会在一小时左右后得到数百个任务 - 我测量了它)。真的很糟糕的设计缺陷,不要试图模仿这个。
当并行运行IO时,无法用经验确定正确的值。这就是为什么TPL如此糟糕。例如,执行顺序IO的磁盘喜欢DOP为1.执行随机的SSD基本上是无限的(100?)。
远程网络服务让您无法知道正确的DOP。您不仅需要进行测试,还需要向所有者请求允许使用可能使其超载的请求来垃圾邮件服务。
我会指定1000作为dop吗?
然后你根本不需要这个设施。只产生所有任务,然后等待所有任务。但1000可能是错误的DOP,因为它没有任何好处压倒DB。
这里似乎用于分区最小数量的异步任务
Parallel.For
的另一个可怕特征。在低CPU机器上,它可能会产生 little 任务。可怕的API。 不将其与IO一起使用。 (我使用AsParallel
允许您设置完全 DOP,而不是最大DOP。)
因为我希望尽可能多地对数据库进行基于IO的调用
为什么?不是一个好的计划。
顺便说一下,你在这里发布的方法很好,我也使用它。我希望它在框架中。这个确切的方法是每周大约10个SO问题的答案(&#34;我如何异步处理100000项并行处理?&#34;)。