【多线程笔记】Parallel

简介

Parallel类是对线程的抽象,提供数据与任务的并行性。
在同步状态下简化Task的使用,也就是使用ForForeachInvoke方法时,调用者线程是阻塞的。

并行方法

Parallel对象提供了3个静态方法来实现 数据和任务的并行

  • Parallel.For
  • Parallel.ForEach
  • Parallel.Invoke

Parallel.ForParallel.ForEach方法在每次迭代的时候调用相同的代码,而Parallel.Invoke()方法允许同时调用不同的方法。Parallel.ForEach()方法用于数据的并行性,Parallel.Invoke()方法用于任务的并行性。
ForForEach方法的返回参数类型ParallelLoopResult

并行返回结果ParallelLoopResult

  • IsCompleted
    并行任务执行的过程是否完整的执行完毕,中途未通过Break()方法来中断,如果使用Break中断则返回false
  • LowestBreakIteration
    返回当前并行任务执行过程种Break()所在的迭代索引。

Parallel.For

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);
});

我们使用了 state.Break();来中断了迭代,
在返回结果中IsCompleted返回的是false,LowestBreakIteration返回了0

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);
            }
posted @ 2020-05-23 16:52  .Neterr  阅读(499)  评论(0编辑  收藏  举报