PLINQ的 ForAll 对比集合的ForEach

  • Post author:
  • Post category:其他


在 PLINQ 中,还可以使用

foreach

执行查询以及循环访问结果。 但是,

foreach

本身不会并行运行,因此,它要求将所有并行任务的输出合并回该循环正在上面运行的线程中。 在 PLINQ 中,在必须保留查询结果的最终排序,以及以按串行方式处理结果时,例如当为每个元素调用

Console.WriteLine

时,则可以使用

foreach

。 为了在无需顺序暂留以及可自行并行处理结果时更快地执行查询,请使用

ForAll

方法执行 PLINQ 查询。

ForEach:进行顺序迭代,不执行并行

ForAll:并行任务

测试代码:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Threading;
  5 using System.Threading.Tasks;
  6 namespace parallelTests
  7 {
  8     class MainClass
  9     {
 10 
 11         public static object _locker = new object ();
 12         public static void Main (string[] args)
 13         {
 14             Console.WriteLine ("Hello World!");
 15 
 16             var lstData = new List<string>{ "a","b","c","d" };
 17 
 18             lstData.AsParallel().ForEach (x => {
 19 
 20                 Thread.Sleep(5*1000);
 21 
 22                 Console.WriteLine("this is:{0}",x);
 23 
 24             });
 25 
 26             Console.ReadKey ();
 27             return;
 28 
 29             //非并行
 30             lstData.ForEach (x => {
 31                 lock (_locker) {
 32                     Thread.Sleep(5*1000);
 33                 }
 34                 Console.WriteLine("this is:{0}",x);
 35 
 36             });
 37 
 38             //  并行
 39 
 40 
 41               lstData.AsParallel().ForAll (x => {
 42 
 43                 //1 同步locker
 44                 lock (_locker) {//--并行locker
 45                     Thread.Sleep(5*1000);
 46                 } 
 47 
 48                 //2 use 并行
 49                 Thread.Sleep(5*1000);
 50 
 51             Console.WriteLine("this is:{0}",x);
 52 
 53             });
 54         
 55 
 56 
 57 
 58 
 59             Console.ReadKey ();
 60 
 61 
 62         }
 63     }
 64 
 65     public static class ForEachExtension
 66     {
 67         //示范: this.GetControls<Button>(null).ForEach(b => b.Enabled = false);
 68         /// <summary>
 69         /// 变量枚举元素  并执行Action
 70         /// </summary>
 71         /// <typeparam name="T"></typeparam>
 72         /// <param name="source"></param>
 73         /// <param name="action"></param>
 74         public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
 75         {
 76             if (source is ParallelQuery<T>)
 77             {
 78                 throw new Exception("ParallelQuery Not Support This Extentsion!");
 79             }
 80             foreach (var item in source)
 81                 action(item);
 82         }
 83 
 84 
 85         /// <summary>
 86         /// 在使用可迭代类型结合进行Count()的替代
 87         /// 防止  yield return 带来的性能问题
 88         /// </summary>
 89         /// <typeparam name="T"></typeparam>
 90         /// <param name="source"></param>
 91         /// <returns></returns>
 92 
 93         public static bool IsEmpty<T>(this IEnumerable<T> source)
 94         {
 95             if (null==source)
 96             {
 97                 return true;
 98             }
 99             return !source.Any();
100         }
101         public static bool IsNotEmpty<T>(this IEnumerable<T> source)
102         {
103             if (null == source)
104             {
105                 return false;
106             }
107             return source.Any();
108         }
109 
110         public static T[] Remove<T>(this T[] objects, Func<T, bool> condition)
111         {
112             var hopeToDeleteObjs = objects.Where(condition);
113 
114             T[] newObjs = new T[objects.Length - hopeToDeleteObjs.Count()];
115 
116             int counter = 0;
117             for (int i = 0; i < objects.Length; i++)
118             {
119                 if (!hopeToDeleteObjs.Contains(objects[i]))
120                 {
121                     newObjs[counter] = objects[i];
122                     counter += 1;
123                 }
124             }
125 
126             return newObjs;
127         }
128     }
129 
130 }