[C #] Parallel programming Parallel,
I. Use of Parallel
Under Parallel, there are three common methods: Invoke, For, and ForEach.
1. Parallel. Invoke
1 public class ParallelDemo 2 { 3 private Stopwatch stopWatch = new Stopwatch(); 4 5 public void Run1() 6 { 7 Thread.Sleep(2000); 8 Console.WriteLine("Task 1 is cost 2 sec"); 9 }10 public void Run2()11 {12 Thread.Sleep(3000);13 Console.WriteLine("Task 2 is cost 3 sec");14 }15 16 public void ParallelInvokeMethod()17 {18 stopWatch.Start();19 Parallel.Invoke(Run1, Run2);20 stopWatch.Stop();21 Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");22 23 stopWatch.Restart();24 Run1();25 Run2();26 stopWatch.Stop();27 Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");28 }29 }
Result of executing Parallel. ParallelInvokeMethod:
We can see that it takes about 5 seconds to call Run1 () and Run2 () normally, and Parallel is used. the Invoke method call value takes about 3 seconds, that is, the time spent by the method with the longest time consumption.
2. Parallel.
This method is similar to the For loop. Add a ParallelForMethod () method to the ParallelDemo class:
1 public void ParallelForMethod() 2 { 3 stopWatch.Start(); 4 for (int i = 0; i < 10000; i++) 5 { 6 for (int j = 0; j < 60000; j++) 7 { 8 } 9 }10 stopWatch.Stop();11 Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");12 13 stopWatch.Reset();14 stopWatch.Start();15 Parallel.For(0, 10000, item =>16 {17 for (int j = 0; j < 60000; j++)18 {19 }20 });21 stopWatch.Stop();22 Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");23 24 }
Running result:
In this example, Parallel. For is less time-consuming than For, but Parallel. For is not always faster than. For example:
1 long sum = 0; 2 stopWatch.Start(); 3 for (int i = 0; i < 10000; i++) 4 { 5 for (int j = 0; j < 60000; j++) 6 { 7 sum++; 8 } 9 }10 stopWatch.Stop();11 Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");12 13 stopWatch.Reset();14 stopWatch.Start();15 Parallel.For(0, 10000, item =>16 {17 for (int j = 0; j < 60000; j++)18 {19 sum++;20 }21 });22 stopWatch.Stop();23 Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");
Use Parallel. for takes more time than three times of For, because Parallel. for runs in parallel, so it accesses sum at the same time, and resource competition will occur, which consumes a lot of time waiting For resources.
3. Parallel. ForEach
Parallel. ForEach is similar to foreach.
1 public void ParallelForEachMethod() 2 { 3 int[] nums = new int[100]; 4 for (int i = 0; i < 100; i++) 5 { 6 nums[i] = i; 7 } 8 stopWatch.Start(); 9 foreach (var item in nums)10 {11 Console.Write(item + "\t");12 }13 stopWatch.Stop();14 Console.WriteLine("\nNormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");15 16 stopWatch.Reset();17 stopWatch.Start();18 Parallel.ForEach(nums, item =>19 {20 Console.Write(item + "\t");21 });22 stopWatch.Stop();23 Console.WriteLine("\nParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");24 }
From 0 to 99, we can see from the running results that the output sequence of Parallel. ForEach is variable, while that of Foreach is output in order.
Ii. Parallel logout and Exception Handling
1. In a serial operation, the break statement can be used to exit the loop, but this is not the case in parallel operations. The delegate parameter of the parallel loop contains a ParallelLoopState. The instance has two methods: Break () and Stop (), which can be used to exit the parallel loop.
Break: of course, this is to notify parallel computing to exit the loop as soon as possible. For example, if parallel computing is iterating 100, then the program will iterate all those less than 100 after break.
Stop: This is different. For example, if you encounter stop in iteration 100, you can quit directly.
The following code tests:
1 public void ParallelBreak() 2 { 3 ConcurrentBag<int> bag = new ConcurrentBag<int>(); 4 Stopwatch stopWatch = new Stopwatch(); 5 stopWatch.Start(); 6 Parallel.For(0, 1000, new ParallelOptions { MaxDegreeOfParallelism = 1 }, (i, state) => 7 { 8 if (bag.Count == 300) 9 {10 state.Stop();11 return;12 }13 bag.Add(i);14 });15 stopWatch.Stop();16 Console.WriteLine("Bag count is " + bag.Count + ", " + stopWatch.ElapsedMilliseconds);17 }
When Parallel. For loops traverse 300 elements, run the Stop () method to exit the loop.
2. Exception Handling
1 public void Run1() 2 { 3 Thread.Sleep(2000); 4 Console.WriteLine("Task 1 is cost 2 sec"); 5 throw new Exception("Exception in task 1"); 6 } 7 public void Run2() 8 { 9 Thread.Sleep(3000);10 Console.WriteLine("Task 2 is cost 3 sec");11 throw new Exception("Exception in task 2");12 }13 public void Run3()14 {15 Thread.Sleep(5000);16 Console.WriteLine("Task 3 is cost 5 sec");17 throw new Exception("Exception in task 3");18 }19 20 public void ParallelInvokeMethod()21 {22 stopWatch.Start();23 try24 {25 Parallel.Invoke(Run1, Run2, Run3);26 }27 catch (AggregateException ex)28 {29 foreach (var item in ex.InnerExceptions)30 {31 Console.WriteLine(item.Message);32 }33 }34 stopWatch.Stop();35 Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");36 37 stopWatch.Restart();38 try39 {40 Run1();41 Run2();42 Run3();43 }44 catch (Exception ex)45 {46 Console.WriteLine(ex.Message);47 }48 stopWatch.Stop();49 Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");50 }
In Parallel. Invoke, the exception of each method is captured. The serial method can capture the exception of run1.