Increasing maximum thread pool size

The thread pool in .NET resides in the System.Threading.ThreadPool class. Generally, there is a lot of discussion around creating your own threads as opposed to using the thread pool. Popular thinking dictates that the thread pool should be used for brief jobs. This is because the thread pool is limited in size. There are many other processes in the system that will use the thread pool. You therefore do not want your application to hog all the threads in the thread pool.

The rule is that you can't set the number of maximum worker or completion threads to be less than the number of processors on your computer. You are also not allowed to set the maximum worker or completion threads to less than the minimum thread pool size.

Getting ready

We will read the number of processors on the current computer. Then, we will get the minimum and maximum allowable thread pool size, generate a random number between the minimum and maximum thread pool size, and set the maximum number of threads on the thread pool.

How to do it…

  1. Create a new method called IncreaseThreadPoolSize() in the Recipes class:
    public class Recipes
    {
        public void IncreaseThreadPoolSize()
        {
            
        }
    }
  2. Start by adding the code to read the number of processors on the current machine using Environment.ProcessorCount:
    public class Recipes
    {
        public void IncreaseThreadPoolSize()
        {
            int numberOfProcessors = Environment.ProcessorCount;
            WriteLine($"Processor Count = {numberOfProcessors}");
        }
    }
  3. Next, we will retrieve the maximum and minimum threads available in the thread pool:
    int maxworkerThreads;
    int maxconcurrentActiveRequests;
    int minworkerThreads;
    int minconcurrentActiveRequests;
    ThreadPool.GetMinThreads(out minworkerThreads, out minconcurrentActiveRequests);
    WriteLine($"ThreadPool minimum Worker = {minworkerThreads} and minimum Requests = {minconcurrentActiveRequests}");
    
    ThreadPool.GetMaxThreads(out maxworkerThreads, out maxconcurrentActiveRequests);
    WriteLine($"ThreadPool maximum Worker = {maxworkerThreads} and maximum Requests = {maxconcurrentActiveRequests}");
  4. Then, we will generate a random number between the maximum and minimum number of threads in the thread pool:
    Random rndWorkers = new Random();
    int newMaxWorker = rndWorkers.Next(minworkerThreads, maxworkerThreads);
    WriteLine($"New Max Worker Thread generated = {newMaxWorker}");
    
    Random rndConRequests = new Random();
    int newMaxRequests = rndConRequests.Next(minconcurrentActiveRequests, maxconcurrentActiveRequests);
    WriteLine($"New Max Active Requests generated = {newMaxRequests}");
  5. We now need to attempt to set the maximum number of threads in the thread pool by calling the SetMaxThreads method and setting it to our new random maximum value for the worker threads and the completion port threads. Any requests above this maximum number will be queued until the thread pool threads become active again. If the SetMaxThreads method is successful, the method will return true; otherwise, it will return false. It is a good idea to ensure that the SetMaxThreads method is successful:
    bool changeSucceeded = ThreadPool.SetMaxThreads(newMaxWorker, newMaxRequests);
    if (changeSucceeded)
    {
         WriteLine("SetMaxThreads completed");
         int maxworkerThreadCount;
         int maxconcurrentActiveRequestCount;
         ThreadPool.GetMaxThreads(out maxworkerThreadCount, out maxconcurrentActiveRequestCount);
          WriteLine($"ThreadPool Max Worker = {maxworkerThreadCount} and Max Requests = {maxconcurrentActiveRequestCount}");
    }
    else
          WriteLine("SetMaxThreads failed");

    Note

    Worker threads is the maximum number of worker threads in the thread pool, while the completion port threads is the maximum number of asynchronous I/O threads in the thread pool.

  6. When you have added all the code in the steps listed, your IncreaseThreadPoolSize() method should look like this:
    public class Recipes
    {
        public void IncreaseThreadPoolSize()
        {
            int numberOfProcessors = Environment.ProcessorCount;
            WriteLine($"Processor Count = {numberOfProcessors}");
                
            int maxworkerThreads;
            int maxconcurrentActiveRequests;
            int minworkerThreads;
            int minconcurrentActiveRequests;
            ThreadPool.GetMinThreads(out minworkerThreads, out minconcurrentActiveRequests);
            WriteLine($"ThreadPool minimum Worker = {minworkerThreads} and minimum Requests = {minconcurrentActiveRequests}");
    
            ThreadPool.GetMaxThreads(out maxworkerThreads, out maxconcurrentActiveRequests);
            WriteLine($"ThreadPool maximum Worker = {maxworkerThreads} and maximum Requests = {maxconcurrentActiveRequests}");
    
            Random rndWorkers = new Random();
            int newMaxWorker = rndWorkers.Next(minworkerThreads, maxworkerThreads);
            WriteLine($"New Max Worker Thread generated = {newMaxWorker}");
    
            Random rndConRequests = new Random();
            int newMaxRequests = rndConRequests.Next(minconcurrentActiveRequests, maxconcurrentActiveRequests);
            WriteLine($"New Max Active Requests generated = {newMaxRequests}");
    
            bool changeSucceeded = ThreadPool.SetMaxThreads(newMaxWorker, newMaxRequests);
            if (changeSucceeded)
            {
                WriteLine("SetMaxThreads completed");
                int maxworkerThreadCount;
                int maxconcurrentActiveRequestCount;
                ThreadPool.GetMaxThreads(out maxworkerThreadCount, out maxconcurrentActiveRequestCount);
                WriteLine($"ThreadPool Max Worker = {maxworkerThreadCount} and Max Requests = {maxconcurrentActiveRequestCount}");
            }
            else
                WriteLine("SetMaxThreads failed");
    
        }
    }
  7. Head on over to your console application and create a new instance of your Recipe class, and call the IncreaseThreadPoolSize() method:
    Chapter7.Recipes oRecipe = new Chapter7.Recipes();
    oRecipe.IncreaseThreadPoolSize();
    Console.ReadLine();
  8. Finally, run your console application and take note of the output:
    How to do it…

How it works…

From the console application, we can see that the processor count is 8. The minimum number of thread pool threads, therefore, also equals 8. We then read the maximum thread pool size and generate a random number between the minimum and maximum numbers. Lastly, we set the maximum thread pool size to our randomly generated minimum and maximum.

While this is only a proof of concept and not something one would do in a production application (setting the thread pool to a random number), it clearly illustrates the ability to set the thread pool to a value specified by the developer.

Tip

The code in this recipe was compiled for 32 bit. Try changing your application to a 64-bit application and run the code again. See the difference 64 bit makes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.11.227