The configuration is one way but lets say you install your application on different machines with different hardware parts like: Numbers of CPU, memory and so on. So better solution is to do it dynamically using code.
Here is a code example on ASP.NET application.
public const string CONNECTION_MANAGEMENT_ALL_IPS = "*";
public const int CONNECTION_MANAGEMENT_THREADS_PER_PROCESSOR = 12;
/// <summary>
/// Add -or- Update system.net --> connectionManagement section.
/// Best Performance for all IPs (12 Threads * CPU#).
/// </summary>
/// <param name="config">The Configuration to be updated.</param>
/// <returns>true if ConnectionManagement section was updated, otherwise return false.</returns>
public static bool ApplyConnectionManagement(Configuration config)
{
return ApplyConnectionManagement(config,
CONNECTION_MANAGEMENT_ALL_IPS,
CONNECTION_MANAGEMENT_THREADS_PER_PROCESSOR * Environment.ProcessorCount);
}
/// <summary>
/// Add -or- Update system.net --> connectionManagement section.
/// </summary>
/// <param name="config">The Configuration to be updated.</param>
/// <param name="address">The Address to be added / updated.</param>
/// <param name="maxConnections">The Max Connections to update.</param>
/// <returns>true if ConnectionManagement section was updated, otherwise return false.</returns>
public static bool ApplyConnectionManagement(Configuration config, string address, int maxConnections)
{
bool isUpdate = false;
if (config == null)
throw new ArgumentNullException("config");
if (String.IsNullOrEmpty(address))
throw new ArgumentNullException("address");
if (maxConnections < 1)
throw new ArgumentException("maxConnections must be greater than zero.", "maxConnections");
NetSectionGroup netSectionGroup = NetSectionGroup.GetSectionGroup(config);
ConnectionManagementSection connectionManagementSection = netSectionGroup.ConnectionManagement;
if (connectionManagementSection.ConnectionManagement.Count == 0)
{
// Add configuration to all IPs (*)
if (address == CONNECTION_MANAGEMENT_ALL_IPS)
{
connectionManagementSection.ConnectionManagement.Clear();
// Add new required element.
ConnectionManagementElement connectionManagementElement =
new ConnectionManagementElement(
address,
maxConnections);
connectionManagementSection.ConnectionManagement.Add(connectionManagementElement);
isUpdate = true;
}
}
else
{
// Update Max Connection for required existing IP.
foreach (ConnectionManagementElement connectionManagementElement in
connectionManagementSection.ConnectionManagement)
{
if (connectionManagementElement.Address == address)
{
if (connectionManagementElement.MaxConnection != maxConnections)
{
connectionManagementElement.MaxConnection = maxConnections;
isUpdate = true;
}
break;
}
}
}
return isUpdate;
}
protected void Application_Start(object sender, EventArgs e)
{
// Load custom configuration file.
Configuration configuration = ConfigurationManager.OpenMachineConfiguration();
string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web.config");
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { MachineConfigFilename = configuration.FilePath, ExeConfigFilename = configPath }, ConfigurationUserLevel.None);
if (ApplyConnectionManagement(config))
{
config.Save(ConfigurationSaveMode.Modified);
}
}
On the first time you apllication start you will write the section using ConfigurationUtils.ApplyConnectionManagement(config) that return true. This will restart your application again but on the next apllication start the ConfigurationUtils.ApplyConnectionManagement(config) will return false.
Thread Pool (minFreeThreads, minLocalRequestFreeThreads):
Here is an example for the config settings:
<
httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="4" />
<processModel maxWorkerThreads="20" maxIoThreads="20" />
Now lets see it in code. first the function that update the thread pool:
/// <summary>
/// Apply Thread Pool Optimized Threading Settings.
/// Max = 100, Min = 50
/// </summary>
public static void ApplyThreadPoolOptimization()
{
int maxWorkerThreads, maxCompletionPortThreads, minWorkerThreads, minCompletionPortThreads;
ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);
ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxCompletionPortThreads);
if (minWorkerThreads < 50) minWorkerThreads = 50;
if (minCompletionPortThreads < 50) minCompletionPortThreads = 50;
if (maxWorkerThreads < 100) minWorkerThreads = 100;
if (maxCompletionPortThreads < 100) maxCompletionPortThreads = 100;
ApplyThreadPoolSettings(maxWorkerThreads, maxCompletionPortThreads, minWorkerThreads, minCompletionPortThreads);
}
/// <summary>
/// Apply Thread Pool Threading Settings.
/// </summary>
/// <param name="maxWorkerThreads">The maximum number of worker threads in the thread pool.</param>
/// <param name="maxCompletionPortThreads">The maximum number of asynchronous I/O threads in the thread pool.</param>
/// <param name="minWorkerThreads">The new minimum number of idle worker threads to be maintained by the thread pool.</param>
/// <param name="minCompletionPortThreads">The new minimum number of idle asynchronous I/O threads to be maintained by the thread pool.</param>
public static void ApplyThreadPoolSettings(
int maxWorkerThreads, int maxCompletionPortThreads,
int minWorkerThreads, int minCompletionPortThreads)
{
ThreadPool.SetMaxThreads(maxWorkerThreads, maxCompletionPortThreads);
ThreadPool.SetMinThreads(minWorkerThreads, minCompletionPortThreads);
}
Again on your global.asax you can add call to update this setting:
protected void Application_Start(object sender, EventArgs e)
{
ApplyThreadPoolOptimization();
}
The settings that are recommended may not work for all applications but If you are making one Web service call to a single IP address from each ASPX page, Microsoft recommends that you use the following configuration settings:
-
Set the values of the maxWorkerThreads parameter and the maxIoThreads parameter to 100.
-
Set the value of the maxconnection parameter to 12*N (where N is the number of CPUs that you have).
-
Set the values of the minFreeThreads parameter to 88*N and the minLocalRequestFreeThreads parameter to76*N.
-
Set the value of minWorkerThreads to 50. Remember, minWorkerThreads is not in the configuration file by default. You must add it.
More information and great microsoft article on this issue can be found on Microsoft Help & Support here.