This problem might occur because ASP.NET limits the number of worker threads and completion port threads that a call can use to execute requests.
Typically, a call to a Web service uses one worker thread to execute the code that sends the request and one completion port thread to receive the callback from the Web service. However, if the request is redirected or requires authentication, the call may use as many as two worker and two completion port threads. Therefore, you can exhaust the managed ThreadPool when multiple Web service calls occur at the same time.
For example, suppose that the ThreadPool is limited to 10 worker threads, and all 10 worker threads are currently executing code that is waiting for a callback to execute. The callback can never execute because any work items that are queued to the ThreadPool are blocked until a thread becomes available.
Another potential source of contention is the maxconnection parameter that the System.Net namespace uses to limit the number of connections. Generally, this limit works as expected. However, if many applications try to make many requests to a single IP address at the same time, threads may have to wait for an available connection.
To resolve these problems, you can tune the following parameters in your Machine.config file to best fit your situation: maxWorkerThreads and maxIoThreads
ASP.NET uses the following two configuration settings to limit the maximum number of worker threads and completion threads that are used:
minFreeThreads and minLocalRequestFreeThreads
ASP.NET also contains the following configuration settings that determine how many worker threads and completion port threads must be available to start a remote request or a local request:
maxconnection
The maxconnection parameter determines how many connections can be made to a specific IP address. The parameter appears as follows:
The settings for the parameters that are discussed earlier in this article are all at the process level. However, the maxconnection parameter setting applies to the AppDomain level. By default, because this setting applies to the AppDomain level, you can create a maximum of two connections to a specific IP address from each AppDomain in your process.
Recommendations
The settings that are recommended in this section may not work for all applications. However, the following additional information may help you to make the appropriate adjustments.
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.
Some of these recommendations involve a simple formula that involves the number of CPUs on a server. The variable that represents the number of CPUs in the formulas is N. For these settings, if you have hyperthreading enabled, you must use the number of logical CPUs instead of the number of physical CPUs. For example, if you have a four-processor server with hyperthreading enabled, then the value of N in the formulas will be 8 instead of 4.
Note When you use this configuration, you can execute a maximum of 12 ASP.NET requests per CPU at the same time because 100-88=12. Therefore, at least 88*N worker threads and 88*N completion port threads are available for other uses (such as for the Web service callbacks).