Thursday, July 28, 2016

Running Functions in Parallel with Microsoft .NET

Parallel computing is a type of computation in which many calculations are carried out simultaneously, or the execution of processes are carried out simultaneously.

.NET 4.5 simplifies this parallel development from the following a normal for loop:

       
for (int i = 0; i < 10; i++)
{
     doSomethingFast(i); //1 execution at a time in this loop.
}



into the following:

Parallel.For(0, 10, new ParallelOptions { MaxDegreeOfParallelism = 4 }, delegate (int i)
{
 doSomethingFast(i); //4 execution at a time in this loop.                
});


If you prefer foreach loop syntax then use the following:




       
String[] fileList = System.IO.Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures", "*.jpg");

foreach(string file in fileList)
{
 doSomethingWithFile(file);
}





       
String[] fileList = System.IO.Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures", "*.jpg");

Parallel.ForEach(fileList, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (file) =>
{
 doSomethingWithFile(file);
});





Below is a full sample program with output screenshot for demonstration.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SimpleParallelProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            //This will call function doSomethingFast in series one at a time.
            Console.WriteLine("This will call function doSomethingFast in series one at a time.");
            executeFunctionSingleSeries();


            Console.WriteLine("\n\nThis will call function doSomethingFast in paralle.");
            //This will call function doSomethingFast in paralle.
            executeFunctionInParalle();

            Console.WriteLine("\n\nThis function will call doSomethingFast and doSomethingFastAtomically in paralle and series respectively.");
            //This function will call doSomethingFast and doSomethingFastAtomically in paralle and series respectively.
            executeFunctionInParalleAndSeries();



            Console.WriteLine("\n\n\nDone, press any key to continue . . . .");
            Console.ReadKey();
        }

        public static void executeFunctionSingleSeries()
        {
            for (int i = 0; i < 10; i++)
            {
                doSomethingFast(i); //1 execution at a time in this loop.
            }
        }
        public static void executeFunctionInParalle()
        {
            Parallel.For(0, 10, new ParallelOptions { MaxDegreeOfParallelism = 4 }, delegate (int i)
            {
                doSomethingFast(i); //4 execution at a time in this loop.                
            });
        }
        private static void executeFunctionInParalleAndSeries()
        {
            Parallel.For(0, 10, new ParallelOptions { MaxDegreeOfParallelism = 4 }, delegate (int i)
            {
                doSomethingFast(i); //4 execution at a time in this loop.                
                doSomethingFastAtomically(i);//1 execution at a time in this loop.
            });
        }




        public static void doSomethingFast(int i)
        {
            Console.WriteLine("doSomethingFast: {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId);

            //rand sleep time between 1 to 3  seconds
            int randomSleepTime = new Random().Next(1, 3) * 1000;
            Thread.Sleep(randomSleepTime);
        }


        private static readonly object doSomethingFastAtomicallyLock = new object();
        public static void doSomethingFastAtomically(int i)
        {
            lock (doSomethingFastAtomicallyLock)
            {
                Console.WriteLine("updateDatabaseAtomically: {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId);

                //rand sleep time between 1 to 3  seconds
                int randomSleepTime = new Random().Next(1, 3) * 1000;
                Thread.Sleep(randomSleepTime);
            }
        }
    }
}


Function execution series vs parallel