C# Thread Pooling

C# Code Snippets Thread Pooling
Share:

About

In this code snippet, we will take a look at thread pools in .NET and C#.

Creating threads and disposing of them when a task is done can be an expensive operation to perform as it uses up time and memory. To mitigate this we can use a thread pool which is essentially a collection of pre instantiated threads. We can assign tasks to these threads. When the task is completed the thread gets returned to the thread pool instead of being disposed of.

The way a thread pool is implemented is you have a class that has a queue of threads and tasks. 

    1. When you initialize the class you would create some threads and put them in the thread queue.
    2. Then you would add some tasks to your task queue.
    3. While tasks are present in the task queue you would keep dequeuing them. For each of the dequeued tasks, you would dequeue a thread and assign it that task.
    4. When the thread completes the task it then gets queued back into the thread queue thus keeping a reference to it and prevent it from being destroyed by the garbage collector. 

However, making your own thread pool is really not advisable as you would just be complicating your life for no reason. Microsoft already made a thread pool in .NET that you can use(and it’s very easy). In this post, I will show how to use the said thread pool. 

Note:

At the end of the day, you should just use the TPL(Task Parallel Library) which is a library made specifically to make multithreading/parallel/asynchronous code execution easier. The TPL already uses a thread pool behind the scenes.   

Let’s have a look at the code below to see how to use the thread pool.

Code:

using System;
using System.Threading;

namespace ThreadPooling
{
    class Program
    {
        static void Main(string[] args)
        {
            //Creating and destroying threads takes up time and memory.
            //To overcome this we can use a thread pool. A thread pool contains threads that are waiting for you to assign them a task.
            //Once a task is given/queued it will be assigned to a thread. 
            //When the task is completed the thread will be put back into the queue(thus keep a reference in memory and avoid being dispossed by the garbage collector) and wait for another task.

            for(int i = 0; i < 10; i++)
            {
                //Queue a task.
                ThreadPool.QueueUserWorkItem(new WaitCallback(doWork), i);
            }
            
            //As you will be able to see in the console output different tasks sometimes reuse the same threads from the thread pool.

            Console.ReadLine();
        }

        public static void doWork(object obj)
        {    
            //Get current thread.
            Thread thread = Thread.CurrentThread;
            //Write out some inforamtion.
            Console.WriteLine($"Task {obj.ToString()} has started. Thread Pool: {thread.IsThreadPoolThread}, Thread ID: {thread.ManagedThreadId}");
            //Simulate doing time consuming work.
            Thread.Sleep(4000);
            //Thread is done.
            Console.WriteLine("Task " + obj.ToString() + " is done.");
        }
    }
}

Resulting output:

Share:

Leave a Reply

Your email address will not be published. Required fields are marked *

The following GDPR rules must be read and accepted:
This form collects your name, email and content so that we can keep track of the comments placed on the website. For more info check our privacy policy where you will get more info on where, how and why we store your data.

Advertisment ad adsense adlogger