使用TPL的并行I / O.

时间:2012-01-22 11:17:41

标签: .net .net-4.0 parallel-processing task-parallel-library

假设有一个文档ID列表,我想从Web服务中检索文档。我是TPL的新手,并且对我未能谷歌的一些最佳实践感兴趣。

我是否正确PLINQ的AsParallel()不适用于此,因为它会对源ID列表进行分区,从而逐个检索单个分区中的文档?

我应该使用LINQ的Select()方法将列表转换为Task<Document>列表,然后转换为WaitAll()吗?

Parallel类和AsParallel()扩展方法都使用下面的Task<T>,不是吗?是否可以将本地状态传递给代理,就像我将其传递给Task(Action<Object>, Object)重载一样?

2 个答案:

答案 0 :(得分:2)

对IO使用AsParallel是危险的,因为您无法精确控制并行度(DOP)。您的IO设备将具有一定的最佳DOP,但这与TPL将使用的不同。

此外,在调用网络功能时,我看到TPL使用的线程数多于处理器数量。这导致网络过饱和和次优吞吐量。它还可能导致超时。由于它的脆弱性,我不会把这样的东西投入生产。

TPL用来选择线程数的算法对我来说并不完全清楚。我认为它试图检测是否添加更多的线程比CPU增加吞吐量。但它将恕我直言,从不使用少于CPU的数量。成像64个线程锤击您的网络服务。

如果您需要精确的并行度,我建议您自己创建所需数量的任务/线程。您可以将此代码放入可重用的辅助函数(“ParallelForeachWithExactDOP”)。

我的建议:如果您只想并行运行所有内容,从而有过度饱和和超时的风险,您确实可以使用Select立即生成所有任务。如果你知道任务的数量将在一个合理的范围内(例如,最多有10个文档),你应该这样做。

这是一个你也可以使用的技巧:将你的文档分成10块。然后,foreach chunk,你立刻生成所有任务并等待所有任务完成。这样,您一次只能处理10个任务。这种方法很简单。但它会提供次优的吞吐量,因为大多数时间运行的任务少于10个,有时甚至没有。认为这是一个简单的初学者技术。

答案 1 :(得分:1)

不确定这是并行化的良好目标,瓶颈将是常见的客户端网络连接。不能从这里说,但除非你有很多未使用的容量(有可能占用网络的风险),或者有一些原因要求一个文件可能阻止你可以在另一个文件上工作,不要以为你会得到很多出于此。

通过Web服务进行并行化,这将成为一个观众。