How to control ThreadPool behavior to avoid thread starvation


Description

Tuning the .NET ThreadPool and HostingEnvironment parameters might help to avoid thread starvation and throttling. The code sample provided in the Solution shows how to:

Solution

  1. Use the code sample from the ConfigureThreadPool.cs file to create a new class.
  2. Build the created class into an assembly.
  3. Put the assembly to the \bin folder of the website.
  4. Reference the class from the configuration by creating a configuration patch file in the \App_Config\Include\zzz folder:
    <?xml version="1.0"?>
    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    	<sitecore>
    		<pipelines>
    			<initialize>
    				<!--
    				Thread pool limits should be configured in machine config, however an access to machine config is not provided in cloud.
    				Thereby API-based approach must be taken.
    				-->
    				<processor type="Sitecore.Support.Pipelines.Loader.ConfigureThreadPool, Sitecore.Support.210408" resolve="true">
    					<MaxConcurrentRequestsPerCPU>8</MaxConcurrentRequestsPerCPU>
    					<!-- <MaxWorkerThreadsPerCore>20</MaxWorkerThreadsPerCore> -->
    					<MinWorkerThreadsPerCore>15</MinWorkerThreadsPerCore>
    					<!-- <MaxCompletionPortThreadsPerCore>20</MaxCompletionPortThreadsPerCore> -->
    					<MinCompletionPortThreadsPerCore>10</MinCompletionPortThreadsPerCore>
    				</processor>
    				<processor type="Sitecore.Analytics.Pipelines.Loader.StartThreadPoolSizeMonitor, Sitecore.Analytics">
    					<patch:delete/>
    				</processor>
    			</initialize>
    		</pipelines>
    	</sitecore>
    </configuration>

    Note: This patch sets maximum and minimum limits for the Worker and IOCP threads of the ThreadPool. The configuration values in the patch are given only as a starting point. The final values must be tuned for each solution as a result of load testing. Pay special attention to the MaxWorkerThreadsPerCore and MaxCompletionPortThreadsPerCore parameters (if you set them specifically). If their values are too low, the application might run out of free threads with a lot of CPU resources left to spare.