Monday 24 April 2017

TPL 05 Parallel class

Tasks are abstractions of threads, they make it easier to build multi-threaded applications. If you need to create threads on a loop, that is for each iteration of your loop you need to fire off a thread then the parallel class may be what you need. The parallel class is appropriate when your for/foreach loops do not need to be run in sequence, but need to process data on each iteration.

using System;
using System.Threading.Tasks;

namespace pc.tplExample04
{
    class Program
    {
        static Random rnd = new Random(DateTime.Now.Millisecond);
        static void Main(string[] args)
        {
            Console.WriteLine("using named method");
            Parallel.For(0, 5, Square);

            Console.WriteLine("using anonymous method");
            Parallel.For(0, 5, delegate (int num)
            {
                Task.WaitAll(Task.Delay(rnd.Next(1000, 2000)));
                Console.WriteLine($"{num} squared is {num * num}");
            });

            Console.WriteLine("using lambda expression");
            Parallel.For(0, 5, num =>
            {
                Task.WaitAll(Task.Delay(rnd.Next(1000, 2000)));
                Console.WriteLine($"{num} squared is {num * num}");
            });
        }

        static void Square(int num)
        {
            Task.WaitAll(Task.Delay(rnd.Next(1000, 2000)));
            Console.WriteLine($"{num} squared is {num * num}");
        }
    }
}


Now if you want to execute a function on a collection of data that implements the IEnumerable interface you can leverage the forEach method of the Parallel class

using System;
using System.Threading.Tasks;

namespace pc.tplExample04
{
    class Program
    {
        static Random rnd = new Random(DateTime.Now.Millisecond);
        static void Main(string[] args)
        {
            var nums = new int[10];
            for (int i = 0; i < nums.Length; i++)
                nums[i] = rnd.Next(5, 15);

            Console.WriteLine("using named method");
            Parallel.ForEach(nums, Square);

            Console.WriteLine("using anonymous method");
            Parallel.ForEach(nums, delegate (int num)
            {
                Task.WaitAll(Task.Delay(rnd.Next(1000, 2000)));
                Console.WriteLine($"{num} squared is {num * num}");
            });

            Console.WriteLine("using lambda expression");
            Parallel.ForEach(nums, num =>
            {
                Task.WaitAll(Task.Delay(rnd.Next(1000, 2000)));
                Console.WriteLine($"{num} squared is {num * num}");
            });
        }

        static void Square(int num)
        {
            Task.WaitAll(Task.Delay(rnd.Next(1000, 2000)));
            Console.WriteLine($"{num} squared is {num * num}");
        }
    }
}