AsParallel究竟是如何工作的?

以下测试程序似乎没有下蹲。 这是因为我正在测试一个小清单吗?

static void Main(string[] args) { List list = 0.UpTo(4); Test(list.AsParallel()); Test(list); } private static void Test(IEnumerable input) { var timer = new Stopwatch(); timer.Start(); var size = input.Count(); if (input.Where(IsOdd).Count() != size / 2) throw new Exception("Failed to count the odds"); timer.Stop(); Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); } private static bool IsOdd(int n) { Thread.Sleep(1000); return n%2 == 1; } 

两个版本都需要4秒才能运行。

Task Parallel Library关注序列的静态类型 。 对于要由TPL处理的操作,它应该是IParallelEnumerable 。 当您调用Test时,您正在将集合强制转换为IEnumerable 。 因此,编译器将解析.Where在序列上调用System.Linq.Enumerable.Where扩展方法而不是TPL提供的并行版本。

(更新.NET4,因为这个问题在Google搜索AsParallel()时排名很高)

只需进行一些更改,您的示例就可以像我想象的那样工作。

Change List list = 0.UpTo(4); to var list = Enumerable.Range(0, 4);

如果您添加了带有ParallelQuery签名的函数重载,那么您的示例将有效…

  private static void Test(ParallelQuery input) { var timer = new Stopwatch(); timer.Start(); int size = input.Count(); if (input.Where(IsOdd).Count() != size / 2) { throw new Exception("Failed to count the odds"); } timer.Stop(); Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); } 

或者,您可以使用LINQ语法….

  private static void Test(ParallelQuery list) { var timer = Stopwatch.StartNew(); if ((from n in list.AsParallel() where IsOdd(n) select n).Count() != (list.Count() / 2)) { throw new Exception("Failed to count the odds"); } Console.WriteLine("Tested " + list.Count() + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); } 

希望这有助于某人!

正如Parallel通过将你的东西放入ThreadPool而工作。 另外,你有多少个核心? 如果你正在使用单核心机器,它仍然需要大约4秒才能运行。