5 days Fun parallel and multi-threaded C # programming - the first day of awareness Parallel

With the advent of the era of multi-core, parallel development increasingly demonstrating its strong power! Use parallel program, full use of system resources and improve program performance. In .net 4.0, Microsoft provides us with a new namespace: System.Threading.Tasks. There are a lot of things about the parallel development, the first to introduce today the most basic and easiest - to understand and use Parallel.

A, Parallel use

There are three common methods invoke, For in Parallel and ForEach below.

1, Parallel.Invoke
this is the easiest, most simple serial code parallelization.

Here to talk about a knowledge point is that the use of StopWatch, recently there are some people that can not find StopWatch, StopWatch in the end what is it today to explain it.

StopWatch in System.Diagnostics named control that you want to use it must first reference the namespace.

Its use is as follows:

var stopWatch = new StopWatch (); // Create an instance Stopwatch

stopWatch.Start (); // start the timer

stopWatch.Stop (); // stop the clock

stopWatch.Reset (); // reset StopWatch

stopWatch.Restart (); // restart stopped StopWatch

stopWatch.ElapsedMilliseconds // get stopWatch from the beginning to the present time difference, in milliseconds

So much of this knowledge is used, and want to learn more about the StopWatch, go to Baidu about it, there are many online information.

Below enter a whole, began to introduce Parallel.Invoke method ado, first create a new console application, add a class, as follows:

public class ParallelDemo
      {
         private Stopwatch stopWatch = new Stopwatch();

         public void Run1()
         {
            Thread.Sleep(2000);
            Console.WriteLine("Task 1 is cost 2 sec");
         }
         public void Run2()
         {
            Thread.Sleep(3000);
            Console.WriteLine("Task 2 is cost 3 sec");
         }

         public void ParallelInvokeMethod()
         {
            stopWatch.Start();
            Parallel.Invoke(Run1, Run2);
            stopWatch.Stop();
            Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Restart();
            Run1();
            Run2();
            stopWatch.Stop();
            Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");
         }
}

The code is simple, add a new first class, write two methods in the class, Run1 and Run2, were waiting for a certain time, outputting a message, then write a test method ParallelInvokeMethod, respectively, and calls Run1 Run2 two ways, and then in the main method call, the following look at how the running time:
Write pictures described here
we should be able to guess, normal call, then it should be more than 5 seconds, while Parallel.Invoke method calls with the only three seconds, which is the longest the method can be seen that methods are executed in parallel, the efficiency has improved a lot.

2、Parallel.For

For this method and circulation functions similar to the following in the class to add a method to test it. code show as below:

public void ParallelForMethod()
     {
            stopWatch.Start();
            for (int i = 0; i < 10000; i++)
            {
               for (int j = 0; j < 60000; j++)
               {
                  int sum = 0;
                  sum += i;
               }
            }
            stopWatch.Stop();
            Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Reset();
            stopWatch.Start();
            Parallel.For(0, 10000, item =>
            {
               for (int j = 0; j < 60000; j++)
               {
                  int sum = 0;
                  sum += item;
               }
            });
            stopWatch.Stop();
            Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");

     }

Wrote two cycles, does not make sense to do some things, main purpose is to consuming CPU time, in the same way to call the main method, operating results in the following figure:
Write pictures described here
you can see, Parallel.For faster than the time spent alone for more than 1 second, showing that increased performance is very impressive. Well, is not Parallel.For at all times faster than for it? Of course the answer is "no", or else keep for Microsoft is also doing?

Here modify the code to add a global variable num, the following code:

public void ParallelForMethod()
         {
            var obj = new Object();
            long num = 0;
            ConcurrentBag<long> bag = new ConcurrentBag<long>();

            stopWatch.Start();
            for (int i = 0; i < 10000; i++)
            {
               for (int j = 0; j < 60000; j++)
               {
                  //int sum = 0;
                  //sum += item;
                  num++;
               }
            }
            stopWatch.Stop();
            Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Reset();
            stopWatch.Start();
            Parallel.For(0, 10000, item =>
            {
               for (int j = 0; j < 60000; j++)
               {
                  //int sum = 0;
                  //sum += item;
                  lock (obj)
                  {
                     num++;
                  }
               }
            });
            stopWatch.Stop();
            Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");

         }

Parallel.For because it is running in parallel, it will also access global variables num, in order to get correct results, to use the lock, this time to look at the results:
Write pictures described here
is not surprised ah? Parallel.For actually took 15 seconds more, while almost for with before. This is mainly due to the parallel simultaneous access to global variables, there will be competition for resources, most of the time consumed in waiting for resources above.

Parallel has been said, you can see it from where it Parallel.For are executed in parallel? Let's write a test code:

Parallel.For(0, 100, i =>
            {
               Console.Write(i + "\t");
            });

Outputted from 0 to 99, the operation will not find sequentially output, for a sequence is affirmative, in parallel at the same time, different output order happens.

3、Parallel.Foreach

This method is very similar to Foreach method, want specific knowledge, you can look at Baidu some information, there is not much to say, given that the use of the following methods:

List<int> list = new List<int>();
            list.Add(0);
            Parallel.ForEach(list, item =>
            {
               DoWork(item);
            });

Two, Parallel loops and exception handling drop-outs

1, when we used to Parallel, it is bound to deal with some of the more time-consuming operation, of course, a waste of CPU and memory, if we are to stop halfway, how to do it?

In the serial code we break it to get, but the parallel is not so simple, but that's okay, provides a delegate parameter ParallelLoopState in parallel cycle,

This example provides a Break and Stop methods to help us achieve.

Break: Of course, this is to inform parallel computing exit the loop as soon as possible, such as parallel computing is an iterative 100, then the program will break after all iterations of less than 100.

Stop: This is not the case, for example, you are suddenly encountered 100 iterations stop, no matter what it was, and exit.

Let's write a piece of code to test:

public void ParallelBreak()
         {
            ConcurrentBag<int> bag = new ConcurrentBag<int>();
            stopWatch.Start();
            Parallel.For(0, 1000, (i, state) =>
            {
               if (bag.Count == 300)
               {
                  state.Stop();
                  return;
               }
               bag.Add(i);
            });
            stopWatch.Stop();
            Console.WriteLine("Bag count is " + bag.Count + ", " + stopWatch.ElapsedMilliseconds);
         }

Used here is Stop, when the number reached 300, it will cease immediately; you can see the results "Bag count is 300", if the break, the result may be more than 300 or 300, we can test.

2, exception handling

  First task is to parallel computing, the process may produce n number of anomalies, how to get to these anomalies do? Exception ordinary and can not get to the anomaly, but the birth of the parallel AggregateExcepation you can get to a set of exceptions.

Here we modify Parallel.Invoke code, modify the code as follows:

public class ParallelDemo
      {
         private Stopwatch stopWatch = new Stopwatch();

         public void Run1()
         {
            Thread.Sleep(2000);
            Console.WriteLine("Task 1 is cost 2 sec");
            throw new Exception("Exception in task 1");
         }
         public void Run2()
         {
            Thread.Sleep(3000);
            Console.WriteLine("Task 2 is cost 3 sec");
            throw new Exception("Exception in task 2");
         }

         public void ParallelInvokeMethod()
         {
            stopWatch.Start();
            try
            {
               Parallel.Invoke(Run1, Run2);
            }
            catch (AggregateException aex)
            {
               foreach (var ex in aex.InnerExceptions)
               {
                  Console.WriteLine(ex.Message);
               }
            }
            stopWatch.Stop();
            Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Reset();
            stopWatch.Start();
            try
            {
               Run1();
               Run2();
            }
            catch(Exception ex)
            {
               Console.WriteLine(ex.Message);
            }
            stopWatch.Stop();
            Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");
         }
}

Call methods in the order I put together a written exception handling, this can only catch exceptions Run1 information, you can write separately. After capturing AggregateException exception, with foreach loop through output abnormality information, abnormality information can see two displays.

Reprinted from http://www.cnblogs.com/yunfeifei/p/3993401.html
source code and more information can go to download View

Guess you like

Origin blog.csdn.net/rui15111/article/details/78789627