AsParallel() 如何拆分它的 'source'?

How does AsParallel() split it's 'source'?

我正在尝试确定 AsParallel() 如何拆分它的 'source',以及 'source' 的真正含义...

例如...

public class CSVItem
{
    public DateTime Date { get; set; }
    public string AccountNumber { get; set; }
}

List<CSVItem> CSVItemList = new List<CSVItem>();

然后将 500k 个不同的 CSVItem 放入 CSVItemList。

然后使用:

CSVItemList = CSVItemList.AsParallel().OrderBy(x => x.AccountNumber).ThenBy(q => q.Date).ToList();

它是否只会将 'source'(意味着例如 250k 记录到两个线程中的每一个)拆分到多个异步线程上并在每个线程上执行 OrderBy().ThenBy() 然后合并结果.. .

或者它将 OrderBy() 和 ThenBy() 分离到单独的线程中,然后 运行 它们然后合并结果...给出一个奇怪的顺序列表?

它一个接一个地走 a) 完成 OrderBy 合并结果,而不是 gose for b) ThenBy。下面的图片形式 Albahari 博客 显示了它是如何工作的,即一张一张

问:有多少个任务

A : 您可以通过使用 WithDegreeOfParallelism 强制 PLINQ 同时 运行 指定数量的任务来决定这一点

   //create 5 task
   List.AsParallel().WithDegreeOfParallelism(5)

检查这个:Parallel Programming

我创建了一个小例子来检查哪个是正确的。

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    static void Main(string[] args)
    {
        List<TestItem> items = new List<TestItem>();
        List<TestItem> itemsNonParallel = new List<TestItem>();

        items.Add(new TestItem() { Age = 1, Size = 12 });
        items.Add(new TestItem() { Age = 2, Size = 1 });
        items.Add(new TestItem() { Age = 5, Size = 155 });
        items.Add(new TestItem() { Age = 23, Size = 42 });
        items.Add(new TestItem() { Age = 7, Size = 32 });
        items.Add(new TestItem() { Age = 9, Size = 22 });
        items.Add(new TestItem() { Age = 34, Size = 11 });
        items.Add(new TestItem() { Age = 56, Size = 142 });
        items.Add(new TestItem() { Age = 300, Size = 13 });

        itemsNonParallel.Add(new TestItem() { Age = 1, Size = 12 });
        itemsNonParallel.Add(new TestItem() { Age = 2, Size = 1 });
        itemsNonParallel.Add(new TestItem() { Age = 5, Size = 155 });
        itemsNonParallel.Add(new TestItem() { Age = 23, Size = 42 });
        itemsNonParallel.Add(new TestItem() { Age = 7, Size = 32 });
        itemsNonParallel.Add(new TestItem() { Age = 9, Size = 22 });
        itemsNonParallel.Add(new TestItem() { Age = 34, Size = 11 });
        itemsNonParallel.Add(new TestItem() { Age = 56, Size = 142 });
        itemsNonParallel.Add(new TestItem() { Age = 300, Size = 13 });

        foreach (var item in items.AsParallel().OrderBy(x => x.Age).ThenBy(x => x.Size))
        {
            Console.WriteLine($"Age: {item.Age}     Size: {item.Size}");
        }

        Console.WriteLine("---------------------------");

        foreach (var item in itemsNonParallel.OrderBy(x => x.Age).ThenBy(x => x.Size))
        {
            Console.WriteLine($"Age: {item.Age}     Size: {item.Size}");
        }

        Console.ReadLine();        
    }
}

public class TestItem
{
    public int Age { get; set; }
    public int Size { get; set; }
}

结果

AsParallel() 做我们想要的。它首先处理 OrderBy() 并行,合并回列表,然后继续下一个查询,在我们的例子中是 ThenBy().