5 days of playing C # parallel and multithreaded programming--the first day to meet parallel

Source: Internet
Author: User

With the advent of the multicore era, parallel development is increasingly demonstrating its power! The use of parallel programs, the full use of system resources, improve the performance of the program. In. NET 4.0, Microsoft has given us a new namespace: System.Threading.Tasks. There are a lot of things about parallel development, and today the first one introduces the most basic, simplest--to recognize and use parallel.

First, the use of parallel

Below parallel there are three common methods Invoke,for and foreach.

1, Parallel.Invoke

This is the simplest and most concise parallelization of serial code.

Here first a knowledge point, is the use of stopwatch, recently some people say that can not find what stopwatch,stopwatch is exactly what things, today to explain.

Stopwatch name the control in System.Diagnostics, it is necessary to refer to this namespace before using it.

Here's how to use it:

var stopWatch = new StopWatch (); Create a Stopwatch instance

Stopwatch.start (); Start timing

Stopwatch.stop (); Stop timing

Stopwatch.reset (); Reset Stopwatch

Stopwatch.restart (); Restarting a stopped stopwatch

Stopwatch.elapsedmilliseconds//Get stopWatch time difference from start to present, Unit is milliseconds

This time to use so much knowledge points, want to know more about stopwatch, go to Baidu a bit, online has a lot of information.

Below into the whole, began to introduce the Parallel.Invoke method, nonsense not much to say, first create a new console program, add a class, the code is as follows:

  Public classParalleldemo {PrivateStopwatch Stopwatch =NewStopwatch ();  Public voidRun1 () {Thread.Sleep ( -); Console.WriteLine ("Task 1 is cost 2 sec"); }          Public voidRun2 () {Thread.Sleep ( the); Console.WriteLine ("Task 2 is cost 3 sec"); }          Public voidParallelinvokemethod () {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 very simple, first add a class, in the class wrote two methods, Run1 and Run2, respectively wait for a certain time, output a message, and then write a test method Parallelinvokemethod, respectively, in two ways to call Run1 and Run2, Then call it in the main method, and take a look at how the run time is:

You should be able to guess that the normal call should be more than 5 seconds, and the Parallel.Invoke method call with only 3 seconds, that is, the longest time-consuming method, you can see that the method is executed in parallel, the efficiency of the implementation is improved a lot.

2, Parallel.For

This method is similar to the function for the for loop, so let's add a method to the class to test it. The code is as follows:

 Public voidParallelformethod () {Stopwatch.start ();  for(inti =0; I <10000; i++)            {                for(intj =0; J <60000; J + +)               {                  intsum =0; Sum+=i; }} stopwatch.stop (); Console.WriteLine ("Normalfor Run"+ Stopwatch.elapsedmilliseconds +"Ms.");            Stopwatch.reset ();            Stopwatch.start (); Parallel.For (0,10000, item =            {                for(intj =0; J <60000; J + +)               {                  intsum =0; Sum+=item;            }            });            Stopwatch.stop (); Console.WriteLine ("ParallelFor Run"+ Stopwatch.elapsedmilliseconds +"Ms."); }

Write two loops, do some meaningless things, the purpose is mainly to consume CPU time, the same is called in the Main method, running results such as:

As you can see, the parallel.for takes more than 1 seconds faster than a simple for-a, and the performance of the boost is very impressive. So, is parallel.for at any time faster than for? The answer, of course, is "no", or Microsoft still has a for?

Modify the code below to add a global variable, num, with the following code:

 Public voidParallelformethod () {            varobj =NewObject (); Longnum =0; Concurrentbag<Long> Bag =Newconcurrentbag<Long>();            Stopwatch.start ();  for(inti =0; I <10000; i++)            {                for(intj =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(intj =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 run in parallel, the global variable num is accessed at the same time, in order to get the correct result, to use lock, this time to see the results of the operation:

Did you have a surprise? Parallel.For took more than 15 seconds, and for the same as before. This is mainly due to concurrent access to global variables, there will be resource contention, most of the time spent on the resource waiting.

Always say parallel, then where can you see that parallel.for is executed in parallel? Let's write a test code below:

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

Output from 0 to 99, after the run will find the output of the wrong order, with the for order is definitely the right, parallel execution at the same time, so there will be a different output order situation.

2, Parallel.ForEach

This method is very similar to the Foreach method, want to know specifically, can Baidu some information to see, here is not much to say, below gives its use method:

list<intnew list<int>();            List. ADD (0);             = =            {               DoWork (item);            });

second, parallel midway exit cycle and exception handling

1, when we use to parallel, is bound to deal with some more time-consuming operation, of course, also consumes CPU and memory, if we stop halfway, how to do?

In the serial code we took a break, but parallelism is not so simple, but it doesn't matter, in the parallel loop of the delegate parameter provides a parallelloopstate,

This example provides the break and stop methods to help us implement it.

Break: Of course this is the notification parallel computation as soon as the exit loop, such as parallel computing is iterating 100, then after break the program will also iterate all less than 100.

Stop: This is not the same, such as the iteration of the 100 suddenly encountered stop, then it doesn't matter, directly exit.

Let's write a code test:

 Public voidParallelbreak () {concurrentbag<int> Bag =Newconcurrentbag<int>();            Stopwatch.start (); Parallel.For (0, +, (i, state) = =            {               if(bag.) Count = = -) {state.                  Stop (); return; } bag.            ADD (i);            });            Stopwatch.stop (); Console.WriteLine ("Bag Count is"+ bag. Count +", "+stopwatch.elapsedmilliseconds); }

Stop is used here, when the number reaches 300, it will stop immediately, you can see the result "Bag count is 300", if you use break, may result in more than 300 or 300, you can test it.

2. Exception handling

The first task is the parallel computation, the processing process may produce more than n exceptions, then how to get these exceptions? Ordinary exception do not get an exception, but aggregateexcepation that are born in parallel can get a set of exceptions.

Here we modify the code for Parallel.Invoke, and the following code is modified:

 Public classParalleldemo {PrivateStopwatch Stopwatch =NewStopwatch ();  Public voidRun1 () {Thread.Sleep ( -); Console.WriteLine ("Task 1 is cost 2 sec"); Throw NewException ("Exception in Task 1"); }          Public voidRun2 () {Thread.Sleep ( the); Console.WriteLine ("Task 2 is cost 3 sec"); Throw NewException ("Exception in Task 2"); }          Public voidParallelinvokemethod () {Stopwatch.start (); Try{Parallel.Invoke (Run1, Run2); }            Catch(aggregateexception aex) {foreach(varExinchAEX. 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."); }}

Sequential call method I write the exception processing, so that only the RUN1 exception information can be captured, we may write separately. After capturing the aggregateexception exception, using a Foreach loop to traverse the output exception information, you can see that two exception information is displayed.

Click here to download the source code

5 days of playing C # parallel and multithreaded programming--the first day to meet parallel

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.