任务并行库(Task Parellel Library)parallel.for parallel.foreach、List、ConcurrentBag 并行集合、线程安全结合

普通的for 、foreach 都是顺序依次执行的。
C#当中我们一般使用for和foreach执行循环,有时候我们呢的循环结构每一次的迭代需要依赖以前一次的计算或者行为。但是有时候则不需要。如果迭代之间彼此独立,并且程序运行在多核处理器上,如果能将不同的迭代放到不同的处理器上并行处理,则会获益匪浅。Parallel.For和Parallel.ForEach就是为此而生的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Parallel中途退出循环和异常处理
1、在串行代码中我们break一下就搞定了,但是并行就不是这么简单了,不过没关系,在并行循环的委托参
数中提供了一个ParallelLoopState,该实例提供了Break和Stop方法来帮我们实现。
Break: 当然这个是通知并行计算尽快的退出循环,比如并行计算正在迭代100,那么break后程序还会迭代所有小于100的。
Stop:这个就不一样了,比如正在迭代100突然遇到stop,那它啥也不管了,直接退出。
2、异常处理
首先任务是并行计算的,处理过程中可能会产生n多的异常,那么如何来获取到这些异常呢?
普通的Exception并不能获取到异常,然而为并行诞生的AggregateExcepation就可以获取到一组异常。

try
{
Parallel.Invoke(Run1, Run2);
}
catch (AggregateException aex)
{
foreach (var ex in aex.InnerExceptions)
{
Console.WriteLine(ex.Message);
}
}
**

线程安全集合

**
List list = new List();
Parallel.For(0, 10000, item =>
{
list.Add(item);
});
Console.WriteLine(“List’s count is {0}”,list.Count());
在这里插入图片描述
看到结果中显示的5851,但是我们循环的是10000次啊!怎么结果不对呢?这是因为List是非线程
安全集合
,意思就是说所有的线程都可以修改他的值。
下面我们来看下并行集合 —— 线程安全集合,在System.Collections.Concurrent命名空间中,首先来
看一下ConcurrentBag泛型集合,其用法和List类似,先来写个方法测试一下:
ConcurrentBag list = new ConcurrentBag();
Parallel.For(0, 10000, item =>
{
list.Add(item);
});
Console.WriteLine(“ConcurrentBag’s count is {0}”, list.Count());
在这里插入图片描述
ConcurrentBag中的数据并不是按照顺序排列的,**顺序是乱的,随机的。**我们平时使用的
Max、First、Last等linq方法都还有。其时分类似Enumerable的用法
关于线程安全的集合还有很多,和我们平时用的集合都差不多,比如类似Dictionary的
ConcurrentDictionary,还有ConcurrentStack,ConcurrentQueue等。

Parallel Linq
public class Custom
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
public static void TestPLinq()
{
Stopwatch sw = new Stopwatch();
List customs = new List();
for (int i = 0; i < 2000000; i++)
{
customs.Add(new Custom() { Name = “Jack”, Age = 21, Address = “NewYork” });
customs.Add(new Custom() { Name = “Jime”, Age = 26, Address = “China” });
customs.Add(new Custom() { Name = “Tina”, Age = 29, Address = “ShangHai” });
customs.Add(new Custom() { Name = “Luo”, Age = 30, Address = “Beijing” });
customs.Add(new Custom() { Name = “Wang”, Age = 60, Address = “Guangdong” });
customs.Add(new Custom() { Name = “Feng”, Age = 25, Address = “YunNan” });
}
sw.Start();
var result = customs.Where(c => c.Age > 26).ToList();
sw.Stop();
Console.WriteLine(“Linq time is {0}.”,sw.ElapsedMilliseconds);
sw.Restart();
sw.Start();
var result2 = customs.AsParallel().Where(c => c.Age > 26).ToList();
sw.Stop();
Console.WriteLine(“Parallel Linq time is {0}.”, sw.ElapsedMilliseconds);
}
在这里插入图片描述
PLINQ
在这里插入图片描述
AsOrdered()与orderby
AsOrdered:保留查询的结果按源序列排序,在并行查询中,多条数据会被分在多个区域中进行查询,查询后再将
多个区的数据结果合并到一个结果集中并按源序列顺序返回。
orderby:将返回的结果集按指定顺序进行排序

//采用 AsOrdered 排序策略 其数据输出结果 是直接将分区数据结果合并起来 并按原始数据顺序排序/
var productListPLinq1 = from product in products.AsParallel().AsOrdered()
where (product.Length == 1)
select product;

var lookupList = customs.ToLookup(i => i.Age);

ToLookup方法是将集合转换成一个只读集合,所以在大数据量分组时性能优于List.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值