在 PLINQ 中,还可以使用 foreach
执行查询以及循环访问结果。 但是,foreach
本身不会并行运行,因此,它要求将所有并行任务的输出合并回该循环正在上面运行的线程中。 在 PLINQ 中,在必须保留查询结果的最终排序,以及以按串行方式处理结果时,例如当为每个元素调用 Console.WriteLine
时,则可以使用 foreach
。 为了在无需顺序暂留以及可自行并行处理结果时更快地执行查询,请使用 ForAll 方法执行 PLINQ 查询。
ForEach:进行顺序迭代,不执行并行
ForAll:并行任务
测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace parallelTests
{
class MainClass
{ public static object _locker = new object ();
public static void Main (string[] args)
{
Console.WriteLine ("Hello World!"); var lstData = new List<string>{ "a","b","c","d" }; lstData.AsParallel().ForEach (x => { Thread.Sleep(*); Console.WriteLine("this is:{0}",x); }); Console.ReadKey ();
return; //非并行
lstData.ForEach (x => {
lock (_locker) {
Thread.Sleep(*);
}
Console.WriteLine("this is:{0}",x); }); // 并行 lstData.AsParallel().ForAll (x => { //1 同步locker
lock (_locker) {//--并行locker
Thread.Sleep(*);
} //2 use 并行
Thread.Sleep(*); Console.WriteLine("this is:{0}",x); }); Console.ReadKey (); }
} public static class ForEachExtension
{
//示范: this.GetControls<Button>(null).ForEach(b => b.Enabled = false);
/// <summary>
/// 变量枚举元素 并执行Action
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action"></param>
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (source is ParallelQuery<T>)
{
throw new Exception("ParallelQuery Not Support This Extentsion!");
}
foreach (var item in source)
action(item);
} /// <summary>
/// 在使用可迭代类型结合进行Count()的替代
/// 防止 yield return 带来的性能问题
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <returns></returns> public static bool IsEmpty<T>(this IEnumerable<T> source)
{
if (null==source)
{
return true;
}
return !source.Any();
}
public static bool IsNotEmpty<T>(this IEnumerable<T> source)
{
if (null == source)
{
return false;
}
return source.Any();
} public static T[] Remove<T>(this T[] objects, Func<T, bool> condition)
{
var hopeToDeleteObjs = objects.Where(condition); T[] newObjs = new T[objects.Length - hopeToDeleteObjs.Count()]; int counter = ;
for (int i = ; i < objects.Length; i++)
{
if (!hopeToDeleteObjs.Contains(objects[i]))
{
newObjs[counter] = objects[i];
counter += ;
}
} return newObjs;
}
} }