How does AsParallel() split it's 'source&#

2019-04-08 11:14发布

I'm trying to determine how AsParallel() splits it's 'source', and indeed what is meant by 'source'...

For example...

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

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

Then put 500k varying CSVItem's into CSVItemList.

Then use:

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

Will it only split the 'source' (meaning for example 250k records onto each of two threads) onto multiple asynch threads and perform the OrderBy().ThenBy() on each thread then merge the results...

Or will it separate the OrderBy() and ThenBy() onto separate threads and run them and then merge the results... giving a strangely ordered list?

2条回答
别忘想泡老子
2楼-- · 2019-04-08 11:39

It gose one by one a) done with OrderBy merge result and than gose for b) ThenBy. Below image form Albahari blog shows how it works i.e. it take one by one

enter image description here

Q: how many number of task

A : you can decide this by using WithDegreeOfParallelism forces PLINQ to run the specified number of tasks simultaneously

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

Check this : Parallel Programming

查看更多
神经病院院长
3楼-- · 2019-04-08 11:42

I created a little example to check, which one is true.

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; }
}

Result

AsParallel() does what we want. It first processes the OrderBy() parallel, merges back the list and then moves on to the next query, in our case ThenBy().

查看更多
登录 后发表回答