.NET Framework 4.0 开始,加入了 Parallel 并行循环语句,这个语句类似于线程,但是用起来更简单。
Parallel.For 与 Parallel.ForEach
using System.Threading.Tasks; Parallel.For(0, count, index => { // 循环 count 次,index 为 [0, count) // do something }); // 此处 For 有 3 个参数,第 3 个参数是个方法,该方法有 1 个参数。 Parallel.ForEach(list, item => { // 循环 list.Count 次 // do something }); // 此处 ForEach 有 2 个参数,第 2 个参数是个方法,该方法有 1 个参数。
原理
就是开多个线程,由于是多线程,所以:
内部循环的顺序并不会得到保证,也就是说并不是执行完了 list[0],再执行 list[1]。
内部使用共享资源时要注意锁定。
循环次数较少时,没必要用。
比线程方便在哪里?
既然还是线程,那比 new Thread 方便在哪里呢?那就是:在 Parallel 执行完之前,主线程不会执行下一句代码。
Console.WriteLine("我准备进循环了"); Parallel.For(0, 3, index => { Thread.Sleep(100); Console.WriteLine(index); }); // 此处 For 有 3 个参数,第 3 个参数是个方法,该方法有 1 个参数。 Console.WriteLine("我已经出循环了"); // 这句总是在 Parallel 干完了(提前 Stop()、Break() 也算),才会执行。而直接创建线程,则不具备这种能力。
不过 new Thread 更灵活,我们可以控制多少个 Thread。
如何提前退出循环?
Parallel.For(0, 3, (int index, ParallelLoopState state) => { state.Stop(); Console.WriteLine(index); }); // 此处 For 有3 个参数,第 3 个参数是个方法,该方法有 2 个参数。
如上,state.Stop() 一被调用就会退出循环,不过当前循环后面的代码 Console.WriteLine(index); 这句,还是会执行的。
Stop() 与 Break() 有何区别?
上述使用 Stop() 退出了循环,其实 Break() 也是可以的,那二者有什么区别呢?
共同点:不会中止已经开始的循环项。
不同点:Break() 是:如果还有比当前 index 小的循环项没有被执行,那就等它们执行,再退出;至于那些比当前 index 大的循环项,就不要管了(已经在执行的继续执行,没执行的不再调用了)。
如何知道执行完毕?
var result = Parallel.For(0, 3, (int index, ParallelLoopState state) => { state.Break(); // do something }); if (result.IsCompleted) // 并不表示 For、ForEach 语句执行完没有,而是表示其中的循环项是否都循环了。 { Console.WriteLine("把每个循环都执行了。"); } else { // 注意:即使所有的循环都执行了,但是只要调用了 Break() 或 Stop(),哪怕是退出循环的最后一刻调用了,都会进这里。 if (result.LowestBreakIteration != null) { Console.WriteLine("使用 Break 提前退出了循环。"); } else { Console.WriteLine("使用 Stop 提前退出了循环。"); } }
注意:即使所有的循环都执行了,但是只要调用了 Break() 或 Stop(),哪怕是退出循环的最后一刻调用了,IsCompleted 都为 false。