Tuesday, May 31, 2011

Parallel Processing in .NET 4.0

I was reading about the new features of .net 4.0 today and found the new parallel processing feature really interesting. The new parallel processing class is called “Task” and it is available in the namespace “System.Threading.Tasks”

The example given below is a comparison of how functions are called in thread model and in the new parallel task way. Though I have included the time taken for to execute the task by each method (thread and task), this example is not specifically to compare performance. It is more about the difference in invoking functions.

I used VS2010 express edition for this test. Though it is easy to do the threading tests in console application, I did this in web application. I implemented ‘ICallbackEventHandler’ and did the example in the “RaiseCallbackEvent” function. For simplicity you can use a console application also.


1) Create a function which does looping as given below

 public string Task1(int iCount)
        {
            DateTime dtStart = DateTime.Now;
            StringBuilder oBuilder = new StringBuilder();
            for (int i = 0; i < iCount; i++)
            {
                oBuilder.Append(i.ToString());
            }
            DateTime dtEnd = DateTime.Now; 
            string strReturn = "Time Taken for Method2 " + dtStart.ToLongTimeString() + "- " + dtEnd.Subtract(dtStart).TotalMilliseconds.ToString(); 
            return strReturn;
        }
2) Since the “ThreadStart” object takes a pointer to void function, I created 4 other functions to test “Thread”
private void Task1Thread()
{
str1 = "\n" + Task1(500000);
}
private void Task2Thread()
{
str2 = "\n" + Task1(600000);
}

private void Task3Thread()
{
str3 = "\n" + Task1(700000);
}

private void Task4Thread()
{
str4 = "\n" + Task1(800000);
}
3) And then I wrote the code to call the functions as below.
DateTime dtStart = DateTime.Now;
switch (eventArgument)
{
case "1":// sequential 
data = Task1(500000);
data = data + "\n" + Task1(600000);
data = data + "\n" + Task1(700000);
data = data + "\n" + Task1(800000);
break;
case "2": //Task - the NEW parallel processing way in .NET 4.0

Task<string> mytask1 = Task<string>.Factory.StartNew(() => Task1(500000));
Task<string> mytask2 = Task<string>.Factory.StartNew(() => Task1(600000));
Task<string> mytask3 = Task<string>.Factory.StartNew(() => Task1(700000));
Task<string> mytask4 = Task<string>.Factory.StartNew(() => Task1(800000));

data = mytask1.Result;
data = data + "\n" + mytask2.Result;
data = data + "\n" + mytask3.Result;
data = data + "\n" + mytask4.Result;

break;
case "3":// Thread – common method of multi threading in .NET 1.1, 2.0

Thread oThread1 = new Thread(new ThreadStart(Task1Thread)); 
Thread oThread2 = new Thread(new ThreadStart(Task2Thread));
Thread oThread3 = new Thread(new ThreadStart(Task3Thread));
Thread oThread4 = new Thread(new ThreadStart(Task4Thread));

oThread1.Start();
oThread2.Start();
oThread3.Start();
oThread4.Start();

oThread1.Join();
oThread2.Join();
oThread3.Join();
oThread4.Join();

data = str1 + str2 + str3 + str4;

break;
}
DateTime dtEnd = DateTime.Now;
string finalTime = "Total Time Taken - " + dtStart.ToLongTimeString() + "- " + dtEnd.Subtract(dtStart).TotalMilliseconds.ToString();

data = data + "\n" + finalTime;


You can see that calling methods using “Task” object is much easier than thread. And also its more efficient than using thread.

No comments: