Task中的Plinq

一:Plinq

问:为什么要使用Plinq?

答:为了能够达到最大的灵活度,Linq又了并行的版本

二:如何把Linq转换为lingq

1.AsParallel():将串行转换为并行

var nums = Enumerable.Range(0, 100).ToList();
            var query = from n in nums.AsParallel()
                        select new
                        {
                            thread = Thread.CurrentThread.ManagedThreadId,
                            nums = n
                        };

        foreach (var item in query)
        {
            Console.WriteLine(item);
        }

1573051666110

2.AsOrdered()

说明:就是将并行结果还是按照未排序的样式排序

var nums = Enumerable.Range(0, 100).ToList();
            nums[0] = 1000;
                var query = from n in nums.AsParallel().AsOrdered()
                            select new
                            {
                                thread = Thread.CurrentThread.ManagedThreadId,
                                nums = n
                            };
foreach (var item in query)
        {
            Console.WriteLine(item);
        }

1573051832978

可以看出,AsOrdered()是按照1-100的排序输出,如果在前面加1000,还是会输出,并不会对结果在排序。

3.AsUnordered就是AsOrdered的相反的意思

4.AsSequential 《==》AsParallel

前者将plinq转换为linq

后者将Linq转换为Plinq

var nums = Enumerable.Range(0, 100).ToList();
    nums[0] = 1000;
        var query = from n in nums.AsParallel().AsSequential()
                    select new
                    {
                        thread = Thread.CurrentThread.ManagedThreadId,
                        nums = n
                    };
foreach (var item in query)
{
    Console.WriteLine(item);
}

1573052174566

线程串行,只有一个线程

5.plinq底层都是用task的,基6于task的一些编程模型,让我们快速进行计算的。

 var nums = Enumerable.Range(0, 100).ToList();
            nums[0] = 1000;
                var query = from n in nums.AsParallel()
                            select new
                            {
                                thread = GetThreadID(),
                                nums = n
                            };
foreach (var item in query)
        {
            Console.WriteLine(item);
        }
        static int GetThreadID()
        {
            Thread.Sleep(1000);
            return Thread.CurrentThread.ManagedThreadId;
        }

1573053268353

6.WithDegreeOfParallelism(Environment.ProcessorCount-1)

设置Task开启线程的数量

7.WithCancellation(source.Token)

 CancellationTokenSource source = new CancellationTokenSource();
    source.Cancel();
     var nums = Enumerable.Range(0, 100).ToList();
    nums[0] = 1000;
    var query = from n in nums.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 1)
                .WithCancellation(source.Token)
                    select new
                    {
                        thread = GetThreadID(),
                        nums = n
                    };
foreach (var item in query)
{
    Console.WriteLine(item);
}

1573053600952

如果执行之前被取消,那就不要执行,会以异常保存。

7.WithExecutionMode:此参数可以告诉系统当前是否强制并行

var query = from n in nums.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 1)
                  .WithCancellation(source.Token)
                  .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                        select new
                      {
                          thread = GetThreadID(),
                          nums = n
                      };

1573053728533

8.WithMergeOptions:

1
2
3
4
5
6
7
8
9
var query = from n in nums.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 1)
.WithCancellation(source.Token)
.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
.WithMergeOptions(ParallelMergeOptions.Default)
select new
{
thread = GetThreadID(),
nums = n
};

1573055734213

聚合计算合并