I. Parallel.For
Parallel.For共有12个重载的方法,这里不每个都讲,只说一个最基本的,其他的大家可以自己尝试。
第一个参数, fromInclusive它可以是Int32型的也可以是Int64型的,注意它是inclusive的,也就是说它在循环体中会被用到,在顺序循环Refactor到并行循环时要注意这一点。
第二个参数, toExclusive它可以是Int32型的也可以是Int64型的,注意它是exclusive的,也就是说它在循环体中不会被用到,在顺序循环Refactor到并行循环时要注意这一点。
它们的区别就类似于下述代码中的0和100这两个值:
第三个参数就是一个Action,它可以是Action<Int32>也可以是Action<Int64>
对开篇中的代码使用Parallel.For后,可以得到下面代码:
1: private static void ParallelQuadraticSum()
2: {
3: double sum = 0;
4: var sw = Stopwatch.StartNew();
5: //for (int i = 0; i < NUM_MAX; i++)
6: //{
7: // sum = sum + (2 * i + 1) * (i + 1) * i / 6;
8: //}
9:
10: Parallel.For(0, NUM_MAX, index => { sum = sum + (2 * index + 1) * (index + 1) * index / 6; });
11:
12: Console.WriteLine("QuadraticSum Excuation Time: {0}", sw.Elapsed.ToString());
13: //Console.WriteLine("Quadratic Result: {0}", sum);
14: //Debug.WriteLine(sw.Elapsed.ToString());
15: }
II. Parallel.Foreach
对于Parallel.Foreach, 一看就能猜到它是用来处理集合类型的, 但是.NET 4对它进行了一定的扩展。
1. 对于普通的foreach循环,一般都用在实现了IEnumerable接口的collection, 同样,对于Parallel.Foreach也可以用于实现了IEnumerable接口的集合。
第一个参数是一个实现了IEnumberable接口的data source
第二个参数是一个action
1: static void Main(string[] args)
2: {
3:
4: List<string> BrowserList = new List<string> { "IE6", "IE8", "IE9", "Firefox", "Safari", "Chrome", "opera" };
5: Parallel.ForEach(BrowserList, item => { Console.WriteLine("The browser is: {0}",item); });
6:
7: Console.ReadLine();
8: }
2. 我们还可以把一个集合里的数据先分成一个一个块,在每一个块里,我们让系统顺序的执行,但是块之间并行执行。
这时候我们需要使用另一个很重要的命名空间中的一个类System.Collections.Concurrent.Partitioner - 分块器.
注意,在这里我们仅仅演示了如何使用分块器;读者要牢记在第一篇文行中提到的两个问题。
1: static void Main(string[] args)
2: {
3:
4: double sum = 0;
5:
6: Parallel.ForEach(System.Collections.Concurrent.Partitioner.Create(1, NUM_MAX), rang =>
7: {
8: for (int i = rang.Item1; i < rang.Item2; i++)
9: {
10: sum = sum + Math.Pow((i * (i + 1) / 2), 2);
11: }
12: });
13:
14: Console.ReadLine();
15: }