Multi Threading - TPL

 02-Jun-2013   NityaPrakash     TPL  MultiThreading    Comments  0

Prominently, a task is a lightweight object for managing a parallelizable unit of work.  A task avoids the overhead of starting a dedicated thread by using the CLR�s thread pool.  It is the same as we call ThreadPool.QueueUserWorkItem to start a thread in thread pool.  This is a best way to leverage multi core process for handling parallel tasks.  Creating and Starting Tasks.

Task

When we want to start a process which doesn�t return any thing and finish silently we use Task.Factory.StartNew.  This method can be used  2 ways: 1. Lambda Expressions:


Task.Factory.StartNew(() =>
{
     for (int i = 0; i < 10; i++)
     {
          Thread.Sleep(100);
          Console.WriteLine(string.Format("counter : {0}", i));
     }
});
It allows multiple parameter to pass. It has the same limitation, if we are using variable inside the method is global, than its going to be shared by all task and manipulation may cause unexpected result. 2. Action Task.Factory.StartNew method excepts the Action parameter. It allows to specify a state object.  Action doesn�t return anything here.  Action object should be declared without parameter or a single parameter type of object.  As illustrated below:

    public static void Main(string[] args)
    {
        Action&lt;object&gt; action = new Action&lt;object&gt;(Process);
        Task.Factory.StartNew(action, "msg");
        Console.ReadLine();
    }

    static void Process(object msg)
    {
        Console.WriteLine("Process 1 started");

        for (int i = 0; i &lt; 10; i++)
        {
            Thread.Sleep(100);
            Console.WriteLine("msg:"+ msg);
        }
        Console.WriteLine("Process 1 finished");
    }

Below code illustrates that how can we call any method with Task Parallel Library:

        public static void Main(string[] args)
        {
            Task.Factory.StartNew(state => Process("nps", "test"), "taskName");
            Console.ReadLine();
        }

    static void Process(string msg, string otherParam)
    {
        Console.WriteLine("Process 1 started");

        for (int i = 0; i &lt; 10; i++)
        {
            Thread.Sleep(100);
            Console.WriteLine("msg:"+ msg + ": other par=&gt;"+otherParam );
        }
        Console.WriteLine("Process 1 finished");
    }

In above code snippet, second parameter is the name of the task.  This will help to debug the code by identifying task with name. Note:  Visual Studio 2010 and above provides a new Parallel Task Window  to help in debugging the task.

Task<TResult>

This generic type of Task can be used when task is returning in current thread.  This is the one big advantage of Tasks over legacy thread pool method.


        public static void Main(string[] args)
        {
            Task<int> task = Task.Factory.StartNew<int>(() =>
                {
                    int multi = 1;
                    for (int i = 1; i <= 10; i++)
                    {
                        Thread.Sleep(100);
                        multi = multi * i; 
                    }
                    return multi;
                });
            Thread.Sleep(100);

        Console.WriteLine("This is main thread");

        int result = task.Result; //Wait for task to finish and fetch result

        Console.WriteLine("Multi :" + result);
        Console.ReadLine();
    }

When we are reading the result from task, it will wait for task to finish and return the result.  At this stage we can handle the exception also.

Child Tasks

Whenever we create any task, those are independent tasks, even created by any other task.  If we use TaskCreationOptions.AttachedToParent when creating task than that task become child task.  So in this case, current task will not be considered completed or finished until all child task finishes.  If we use Wait() function with parent task, parent task wait until all all child task finishes.

Advantages of TPL

Task provides following features:

  • Tune a task�s scheduling
  • Establish a parent/child relationship when one task is started from another
  • Implement cooperative cancellation
  • Wait on a set of tasks
  • Attach �continuation� tasks
  • Schedule a continuation based on multiple antecedent tasks
  • Exception handling

Conclusion

I have demoed here various option and ways to create tasks.  Task is just a another way to add threads in thread pool, but very controlled way.   Adding thread in thread pool is always an efficient way rather creating manual thread.  If lots of thread created than it can degrade the performance rather than improving it.  I�ll come up more topics on TPL


Nitya Prakash Sharma has over 10 years of experience in .NET technology. He is currently working as Senior Consultant in industry. He is always keen to learn new things in Technology and eager to apply wherever is possible. He is also has interest in Photography, sketching and painting.

My Blog
Post Comment

COMMENTS