【发布时间】:2022-02-07 17:05:36
【问题描述】:
我喜欢 PLINQ。在我所有关于各种并行化模式的测试用例中,它都表现良好且始终如一。但是我最近遇到了一个让我有点困扰的问题:这两个示例之间的功能区别是什么?什么(如果有的话)使 PLINQ 示例与以下反模式不相似或不等价?
PLINQ:
public int PLINQSum()
{
return Enumerable.Range(0, N)
.AsParallel()
.Select((x) => x + 1)
.Sum();
}
通过异步同步:
public int AsyncSum()
{
var tasks = Enumerable.Range(0, N)
.Select((x) => Task.Run(() => x + 1));
return Task.WhenAll(tasks).Result.Sum();
}
【问题讨论】:
-
一个观察到的行为差异:在我的测试中,其中 N 是要完成的操作数,M 是操作的大小,随着 N 的增加和 M 的减少,PLINQ 保持同步或低于同步运行时,而上面的异步示例比同步测试慢了几个数量级。
-
见this answer。它讨论了
foreach中Parallel.ForEach与Task.Run之间的区别,但这同样适用于PLINQ。 -
您的情况的另一个区别是,一旦您将
Task.Run嵌套在Select中,您就会使用Task<int>对象而不是int值,因此您不能轻易链接其他 PLINQ 操作(例如Where),而无需等待这些任务完成。
标签: c# async-await parallel-processing plinq