0x00 介绍
Parallel类是对线程的抽象,提供数据与任务的并行性。类定义了静态方法For和ForEach,使用多个任务来完成多个作业。Parallel.For和Parallel.ForEach方法在每次迭代的时候调用相同的代码,而Parallel.Invoke()方法允许同时调用不同的方法。Parallel.ForEach()方法用于数据的并行性,Parallel.Invoke()方法用于任务的并行性。
以下内容只针对我在项目中使用到的情况进行记录,当然还有更多的重载和实现没有讲解出来。
0x01 命名空间
Parallel 所在的命名空间是 System.Threading.Tasks,看名字就知道与线程,任务有关。
使用时 using System.Threading.Tasks;即可使用Parallel类的方法
0x02 并行方法
Parallel对象提供了3种方法来实现 数据和任务的并行
- Parallel.For
- Parallel.ForEach
- Parallel.Invoke
0x03 并行返回结果 ParallelLoopResult
ParallelLoopResult 提供了以下两个属性
//
// 摘要:
// 获取该循环是否已运行完成(即,该循环的所有迭代均已执行,并且该循环没有收到提前结束的请求)。
//
// 返回结果:
// 如果该循环已运行完成,则为 true;否则为 false。
public bool IsCompleted { get; }
//
// 摘要:
// 获取从中调用 System.Threading.Tasks.ParallelLoopState.Break 的最低迭代的索引。
//
// 返回结果:
// 返回一个表示从中调用 Break 语句的最低迭代的整数。
public long? LowestBreakIteration { get; }
- IsCompleted
并行任务执行的过程是否完整的执行完毕,中途未通过Break()方法来中断,如果使用Break中断则返回false - LowestBreakIteration
返回当前并行任务执行过程种Break()所在的迭代索引。
0x04 Parallel.For
通过下面代码我们来了解下 Parallel.For 的运行方式,
第一个参数是迭代开始的值,
第二个参数是迭代结束的值,
第三个参数是 一个委托方法该方法有两种比较常用的重载
- 第一种重载方法
(i)=>{}
ParallelLoopResult result = Parallel.For(0, 10, (i) =>
{
Console.WriteLine("Task: count={0},id={1},threadid={2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
//your business code
Thread.Sleep(1000);
});
//result 查看返回的状态
Console.WriteLine("Is Break = {0}", !result.IsCompleted);
Console.WriteLine("Break Index = {0}", result.LowestBreakIteration);
运行结果

- 第二种重载方法
(i,state)=>{}
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();
Thread.Sleep(1000);
});
//result 查看返回的状态
Console.WriteLine("Is Break = {0}", !result.IsCompleted);
Console.WriteLine("Break Index = {0}", result.LowestBreakIteration);
运行结果

再结果中 我们看到 第二种方式 我们使用了 state.Break();来中断了迭代,
在返回结果中IsCompleted返回的是false,LowestBreakIteration返回了0
但是在任务里却执行了两次任务,说明 Break()方法并不能中断已经提交的并行任务。
0x05 Parallel.ForEach
Parallel.ForEach的运行原理跟For相似,只是参数不同
第一个参数是集合对象
第二个参数是一个委托方法该方法有三种比较常用的重载
- 第一种重载方法
(v)=>{}
String[] Items = new String[] { "A", "B", "C", "D", "E", "F", "G" };
ParallelLoopResult result = Parallel.ForEach(Items,value =>
{
Console.WriteLine("Task: value={0},id={1},threadid={2}", value, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
//your business code
//state.Break();
Thread.Sleep(1000);
});
//result 查看返回的状态
Console.WriteLine("Is Break = {0}", !result.IsCompleted);
Console.WriteLine("Break Index = {0}", result.LowestBreakIteration);
运行结果

- 第二种重载方法
(v,state)=>{}
String[] Items = new String[] { "A", "B", "C", "D", "E", "F", "G" };
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);
});
//result 查看返回的状态
Console.WriteLine("Is Break = {0}", !result.IsCompleted);
Console.WriteLine("Break Index = {0}", result.LowestBreakIteration);
运行结果

- 第三种重载方法
(v,state,i)=>{}
String[] Items = new String[] { "A", "B", "C", "D", "E", "F", "G" };
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);
});
//result 查看返回的状态
Console.WriteLine("Is Break = {0}", !result.IsCompleted);
Console.WriteLine("Break Index = {0}", result.LowestBreakIteration);
运行结果

0x06 Parallel.Invoke
Parallel.Invoke属于方法级别的并行
它的参数params Action[] actions
和 ParallelOptions parallelOptions, params Action[] actions 两种重载方法
其中 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());
本文深入解析了.NET Framework中Parallel类的功能,包括Parallel.For、Parallel.ForEach和Parallel.Invoke方法的使用,以及ParallelLoopResult返回结果的解读。文章通过代码示例展示了如何利用这些方法实现数据和任务的并行处理,特别关注于中断迭代和取消并行任务的机制。

1607

被折叠的 条评论
为什么被折叠?



