Multi Threading - Part2

 28-May-2013   NityaPrakash     MultiThreading  ThreadPool    Comments  0

Whenever we start a thread, a few hundred microseconds are spent organizing such things like fresh private local variable stack.  Each thread also consumes by default 1MB of memory.  The thread pool reduce these overheads by sharing and recycling threads.  This is very useful when leveraging multicore processors to execute computationally intensive code. 

The Thread pool controls the total number of threads will run simultaneously.  Once limit is reached, jobs queue up and start only when another finishes.

Enter the Thread Pool

There are several way to enter in thread pool:

  • Via the Task Parallel Library(TPL)

  • By calling ThreadPool.QueueUserWorkItem

  • Via asynchronous delegates

  • Via BackgroundWorker

Following constructs uses the thread pool indirectly:

  • WCF, Remoting, ASP.NET and ASMX Web Services

  • System.Timers.Timer and System.Threading.Timer

  • Framework methods that end in Async

  • PLINQ

We cannot set the Name of a pooled thread.   Pooled threads are always background threads

Entering the Thread Pool

QueueUserWorkItem

We can add  a process in ThreadPool.QueueUserWorkItem Asynchronous delegate.  This method add the work item in thread pool queue.  If there is no thread or less threads running and thread pool can except more work to process, it will start the process immediately.  If thread pool is already busy executing maximum number of threads than new process will be queued up. As soon as any existing process finishes it will start processing new work item.  Below code illustrate the thread pool entry


       public static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(Process); //Without parameter
            ThreadPool.QueueUserWorkItem(Process, "P1");
            Console.ReadLine();
        }

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

            for (int i = 0; i < 10; i++)
            {
                Thread.Yield();
                Console.Write("msg:"+ msg);
            }
            Console.WriteLine("Process 1 finished");
        }

Process being queued up in thread pool, must except one object type parameter.  Same method will be used for parameterized and non-parameterized call.  In this case we can�t return the processed value in calling thread(Main thread in this case.).

Asynchronous delegate

There are two advantages of using this technique over previous method:

  • We can pass/return any number of values in the method need to execute asynchronously.

  • If any exception occur in the executing method which is added in thread pool, is re-thrown in original (calling thread).

We can turn any normal method in to asynchronous method via to special delegates provided by .NET framework,  Func and Action.  Func is delegate which can point to any method that return any value and Action is pointer to a function which doesn�t return anything (Void).



        public static void Main(string[] args)
        {

            Action<object> method = new Action<object>(Process);
            method.BeginInvoke("Action", ProcessDone, method);
            Console.ReadLine();
        }

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

            for (int i = 0; i < 10; i++)
            {
                Thread.Yield();
                Console.Write("msg:"+ msg);
            }
            Console.WriteLine("Process 1 finished");
        }

        static void ProcessDone(IAsyncResult result)
        {
            try
            {
                var target = (Action<object>)result.AsyncState;
                target.EndInvoke(result);
                Console.WriteLine("Process is finished");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

Thread pool�s minimum and maximum size can be set to optimize the performance.  But I think, we should let OS and Thread pool decide how many thread the can process without hurting overall performance of the system.


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