在 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 }