有时候我们对大批量数据进行处理,此时并行linq就起作用了.
并行查询
对于以下查询可以耗时会非常大,如下:
const int arraySize = ;
var r = new Random();
var a = Enumerable.Range(, arraySize).Select(x => r.Next());
var c = a.Where(x => Math.Log(x) < ).Select(x => x).Average();
这时候我们可以使用linq中的并行解决方案(使用了AsParallel())
),如果你的CPU支持多核,运行以下代码你会看到效果:
const int arraySize = ;
var r = new Random();
var a = Enumerable.Range(, arraySize).Select(x => r.Next());
var c = a.AsParallel(). Where(x => Math.Log(x) < ).
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) <
select cc).Average();
Console.WriteLine(res);
}
catch (OperationCanceledException ex)
{
Console.WriteLine("");
Console.ReadKey();
}
});
Console.WriteLine("query start");
Console.Write("cancel?");
string input = Console.ReadLine();
if (input.ToLower().Equals("y"))
{
cts.Cancel();
}
因为通过Task.Factory.StartNew是创建的异步执行任务,我们在此操作中创建了一个令牌,如果在查询结果出来之前,我们输入了y,那么语句中的查询就不会执行了,这种情况下
多用于查询任务过长的时候使用.