并行Linq

  有时候我们对大批量数据进行处理,此时并行linq就起作用了.

  并行查询

  对于以下查询可以耗时会非常大,如下:

 const int arraySize = 100000000;
            var r = new Random();
            var a = Enumerable.Range(0, arraySize).Select(x => r.Next(140));
var c = a.Where(x => Math.Log(x) < 4).Select(x => x).Average();

这时候我们可以使用linq中的并行解决方案(使用了AsParallel())

),如果你的CPU支持多核,运行以下代码你会看到效果:

  const int arraySize = 100000000;
            var r = new Random();
            var a = Enumerable.Range(0, arraySize).Select(x => r.Next(140));
            var c = a.AsParallel(). Where(x => Math.Log(x) < 4).
                       Select(x => x).Average();

我可以附上截图:以下调整之前的运行结果:

以下为调整之后的结果(加了AsParallel())

经过多次测试, 速度基本上快2到3秒,并且我的电脑是i3(两盒的),如果电脑配置更高,或许速度更快.

虽然速度快了,但从图中可以看出占用的CPU和内存也同样提高了,但是对于现在电脑的配置我觉着内存和CPU可以不用考虑了.

 取消

.net 提供了一种标准方式,来取消长时间运行的任务,这也适应于并行Linq

var cts = new CancellationTokenSource();

            Task.Factory.StartNew(() =>
            {
                try
                {
                    var res = (from cc in a.AsParallel().WithCancellation(cts.Token)
                               where Math.Log(cc) < 4
                               select cc).Average();
                    Console.WriteLine(res);
                }
                catch (OperationCanceledException ex)
                {
                    Console.WriteLine("3433");
                    Console.ReadKey();
                }
            });
            Console.WriteLine("query start");
            Console.Write("cancel?");
            string input = Console.ReadLine();
            if (input.ToLower().Equals("y"))
            {
                cts.Cancel();
            }

因为通过Task.Factory.StartNew是创建的异步执行任务,我们在此操作中创建了一个令牌,如果在查询结果出来之前,我们输入了y,那么语句中的查询就不会执行了,这种情况下

多用于查询任务过长的时候使用.

posted @ 2017-04-24 00:40  tuohaibei  阅读(806)  评论(0编辑  收藏  举报