Click here to Skip to main content
15,894,740 members
Articles / General Programming / Threads
Tip/Trick

The five minute guide to Parallel Programming in c#.

Rate me:
Please Sign up or sign in to vote.
4.69/5 (6 votes)
22 Jan 2014CPOL4 min read 28.8K   9  
Working introduction to Parallel Programming

Objective 

This tip is a quick "get up and running" introduction to parallel programming using a working example rather than any theory.

Example Origin 


When I adopted the message handler approach to distributing ticket data between busses and their control office, my initial instinct was that this tailor made for a parallel solution with each datastore on its own thread. It quickly occured to me that this was a sure and certain way to corrupt my database. e.g  the row to record a ticket validation could be created before the row to record the sale of the same ticket if its thread got priority!

However as time moved on a scenario has evolved that is ideally suited to parallel programming. When a customer with a series of unpaid tickets makes a payment to cover the outstanding amount, this payment is initially recorded in sequence with any other associated data, e.g. a preceeding sale. Then I need to kick off a task which writes a contra entry to the account for the funds of the to be redistributed, and scans the purchase list for that customer beginning with the oldest unpaid ticket and writes an entry to pay each off until either the funds are used up or that customer has no more tickets with money owed on them. There is no technical database dependency on this task, and if run sequentially could present a performance bottleneck.

 

Using the Sample Code

I used Listing 2-4 of Adam Freeman's book "Pro .NET 4 Parallel Programming in C# as my template.

I started with a standard C# console application, and included the System.Threading namespace. I renamed the application's autogenerated class from "Program" to "ParallelTest". Then I added a static integer method, "Timed_Message" to take a  message string and an interval as arguments. This method loops 10 times and sends text to the console at intervals based on the interval argument supplied.

The main method spawns two tasks each calling "Timed_Message", but supplying different text and interval values for each instance. There is a final Console.Readline to prevent the main thread from concluding and killing off the sub threads before they get the opportunity to show how they work together. This is the code:

<pre>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ParallelTest
{
    class ParallelTest
    {
        private static int Timed_Message(String arg_Message, int arg_Interval)
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Source {0} - Cycle {1} for Interval {2}", arg_Message, i, arg_Interval);
                Thread.Sleep(1000 * arg_Interval);
            }

            Console.WriteLine("{0} - Complete", arg_Message);
            return 0;
        }

        static void Main(string[] args)
        {
            int RetCode = 0;
            Task RedistributionTask = new Task(() => RetCode = Timed_Message("Five ", 4));
            RedistributionTask.Start();
            Task AltRedistributionTask = new Task(() => RetCode = Timed_Message("Three ", 2));
            AltRedistributionTask.Start();
            //Timed_Message("Main", 6);

            // wait for input before exiting
            Console.WriteLine("Press enter to finish after both [Complete] messages appear.");
            Console.ReadLine();
        }

    }
}
</pre>

Press enter to finish after both [Complete] messages appear.
Source Five  - Cycle 0 for Interval 4
Source Three  - Cycle 0 for Interval 2
Source Three  - Cycle 1 for Interval 2
Source Five  - Cycle 1 for Interval 4
Source Three  - Cycle 2 for Interval 2
Source Three  - Cycle 3 for Interval 2
Source Five  - Cycle 2 for Interval 4
Source Three  - Cycle 4 for Interval 2
Source Three  - Cycle 5 for Interval 2
Source Five  - Cycle 3 for Interval 4
Source Three  - Cycle 6 for Interval 2
Source Three  - Cycle 7 for Interval 2
Source Five  - Cycle 4 for Interval 4
Source Three  - Cycle 8 for Interval 2
Source Three  - Cycle 9 for Interval 2
Source Five  - Cycle 5 for Interval 4
Three  - Complete
Source Five  - Cycle 6 for Interval 4
Source Five  - Cycle 7 for Interval 4
Source Five  - Cycle 8 for Interval 4
Source Five  - Cycle 9 for Interval 4
Five  - Complete

Try this at home.

Uncomment the line Timed_Message("Main", 6);  in the main method and re run the application. Now you will see the main thread running in parallel with the other two, and because we have used a longer interval, it continues working after the other two are done.  This is an extract from the revised output :

Source Main - Cycle 3 for Interval 6
Source Three  - Cycle 9 for Interval 2
Source Five  - Cycle 5 for Interval 4
Three  - Complete
Source Main - Cycle 4 for Interval 6
Source Five  - Cycle 6 for Interval 4
Source Five  - Cycle 7 for Interval 4
Source Main - Cycle 5 for Interval 6
Source Five  - Cycle 8 for Interval 4
Source Main - Cycle 6 for Interval 6
Source Five  - Cycle 9 for Interval 4
Five  - Complete
Source Main - Cycle 7 for Interval 6
Source Main - Cycle 8 for Interval 6
Source Main - Cycle 9 for Interval 6
Main - Complete
Press enter to finish after both [Complete] messages appear.

History 

22-Jan-2014 1.0 Initial post

22-Jan-2014 1.1 Code reformatted


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Ireland Ireland
My first program was written in Basic on a Sinclair Spectrum ZX 16K in the summer of '85. Having studied Computer Systems I attempted to break into the world of C but took a wrong turn and got immersed in COBOL!

I looked a C again in 1994 but didnt follow up on it. In 2001 I introduced myself to Visual C++ 6.0 courtesy of Ivor Hortons book, but found the going difficult. I tipped my toe in the .NET water in '05 but the first example I tried in VC++ 2005 express didnt work and allied with the absence of MFC in the express package, I parked that up.

Along the way my career got shunted into software testing

A personal machine change force me to migrate to VS2008 in 2008. The new edition of Ivor Hortons book for VC++ in VS2008 reintroduced me to .NET and I got curious whereupon I went out and acquired Stephen Fraser's "Pro Visual C++/CLI and
the .NET 3.5 Platform". I was hooked!

After 20 years I think I finally found my destination.

But it would take a further 8 years of exile before I was reappointed to a developer role. In that time I migrated to C# and used selenium wedriver (courtesy of Arun Motoori's Selenium By Arun) as the catalyst to finally grab the opportunity.

Comments and Discussions

 
-- There are no messages in this forum --