use*_*872 5 .net c# multithreading task-parallel-library async-await
我最近发现了以下代码,可以有效地运行大量的IO绑定任务(参见链接). http://blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx
我的印象如下:
我的问题是,由于Parallel.ForEach本身有自己的MaxDegreeOfParallelism,我如何知道在IEnumerable扩展的示例代码中定义dop参数的内容?
例如,如果我要处理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);
}));
}
Run Code Online (Sandbox Code Playgroud)
Parallel.ForEach 本质上有自己的 MaxDegreeOfParallelism
好吧,随着时间的推移,内置的启发式方法Parallel.ForEach
很容易产生大量任务(如果你的工作项目有 10 毫秒的延迟,你会在一小时左右后获得数百个任务 - 我测量了它)。真的很糟糕的设计缺陷,不要试图模仿这个。
并行运行 IO 时,无法替代凭经验确定正确的值。这就是TPL在这方面如此糟糕的原因。例如,执行顺序 IO 的磁盘喜欢 DOP 为 1。执行随机的 SSD 喜欢基本上无限(100?)。
远程 Web 服务无法让您知道正确的 DOP。您不仅需要测试,还需要请求所有者允许向服务发送垃圾邮件,这些请求可能会导致服务过载。
我会指定 1000 作为 dop 吗?
那么你就根本不需要这个设施了。只需生成所有任务,然后等待所有任务。但 1000 可能是错误的 DOP,因为它压倒了 DB 而没有任何好处。
这里它似乎用于划分异步任务的最小数量
的另一个可怕的功能Parallel.For
。在 CPU 较低的机器上,它可能会产生一些小任务。可怕的 API。不要将其与 IO 一起使用。(我使用AsParallel
它允许您设置精确的DOP,而不是最大 DOP。)
因为我想对尽可能多的基于 IO 的数据库调用进行排队
这是为什么?这不是一个好计划。
顺便说一句,你在这里发布的方法很好,我也使用这个。我希望它在框架内。这个确切的方法是每周大约 10 个 SO 问题的答案(“如何异步并行处理 100000 个项目?”)。
归档时间: |
|
查看次数: |
302 次 |
最近记录: |