Parallel类是对线程的抽象,提供数据与任务的并行性。
在同步状态下简化Task的使用,也就是使用For、Foreach、Invoke方法时,调用者线程是阻塞的
类定义了静态方法For和ForEach,使用多个任务来完成多个作业。Parallel.For和Parallel.ForEach方法在每次迭代的时候调用相同的代码,而Parallel.Invoke()方法允许同时调用不同的方法。Parallel.ForEach()方法用于数据的并行性,Parallel.Invoke()方法用于任务的并行性。
For、ForEach方法的返回参数类型ParallelLoopResult
提供两个属性:
IsCompleted:循环是否执行完成,中途未通过Break()方法中断,如果使用Break中断则返回false
LowestBreakIteration:返回当前并行任务执行过程中Break()所在的迭代。
Parallel.ForEach案例:
ParallelLoopResult result = Parallel.For(0, 10, (i,state) => { Console.WriteLine("Task: count={0},id={1},threadid={2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId); //your business code state.Break();//相当于continue, Break()方法并不能中断已经提交的并行任务,所以执行次数比实际多 Thread.Sleep(1000); });
Parallel.ForEach
Parallel.ForEach的运行原理跟For相似
重载1:
ParallelLoopResult result = Parallel.ForEach(Items,(value, state) => { Console.WriteLine("Task: value={0},id={1},threadid={2}", value, Task.CurrentId, Thread.CurrentThread.ManagedThreadId); //your business code // state.Break(); Thread.Sleep(1000); });
重载2:
ParallelLoopResult result = Parallel.ForEach(Items,(value, state,i) => { Console.WriteLine("Task: value={0},id={1},threadid={2},count={3}", value, Task.CurrentId, Thread.CurrentThread.ManagedThreadId,i); //your business code state.Break(); Thread.Sleep(1000); });
Parallel.Invoke
Parallel.Invoke属于方法级别的并行,参数 ParallelOptions 提供了取消并行任务的信号
ParallelOptions parallelOptions = new ParallelOptions(); CancellationTokenSource tokenSource = new CancellationTokenSource(); //最大允许10个任务并行 parallelOptions.MaxDegreeOfParallelism = 10; //取消并行的信号 parallelOptions.CancellationToken = tokenSource.Token; //你可以在并行任务的过程中调用Cancel方法取消并行任务 //tokenSource.Cancel(); Action[] actions = new Action[] {() => { Thread.Sleep(1000); Console.WriteLine("taks1...."); }, () => { Thread.Sleep(1000); Console.WriteLine("task2....."); }}; Parallel.Invoke(actions.ToArray());
将Linq转化成PLinq:
AsParallel() 串行代码转化为并行
AsSequential() 与AsParallel()相反,并行代码转化为串行
AsOrdered() 按集合原始顺序排序
AsUnordered() 不按照原始的顺序排序
.WithDegreeOfParallelism(Environment.ProcessorCount) 设置线程数
.WithCancellation(token) 如果之前已经取消,就不执行
IEnumerable<int> nums = Enumerable.Range(0, 100); var os =from n in nums.AsParallel().AsOrdered() select new {num=n,threadID=Thread.CurrentThread.ManagedThreadId }; foreach (var item in os) { System.Console.WriteLine(item); }