When you use the System.Net.HttpWebRequest and
the System.Net.HttpWebResponse classes in an application that uses a thread pool,
you may receive the following error message:
System.InvalidOperationException: There were not enough free
threads in the ThreadPool object to complete the
operation
The System.Net.HttpWebRequest and the System.Net.HttpWebResponse
classes always use asynchronous methods to complete a request. When the
asynchronous request is made, ASP.NET uses a new thread from the ThreadPool object.
When ASP.NET does not find a thread, the System.Net.HttpWebRequest class returns the error message
instead of queuing the request.
To work around this problem, use one of
the following methods:
Use a Try-Catch block in the code to catch the
exception and to handle it appropriately.
Implement a queuing mechanism to keep the exception
from occurring.
If you are using ASP.NET in Microsoft Internet Information Services 5.0 or later, reconfigure the thread pool size in the Machine.config
file. To do this, follow these steps:
Open the Machine.config file from the %Systemroot%\Microsoft.NET\Framework\Version\CONFIG folder.
In the <processModel> section of the
Machine.config file, configure the value of the maxWorkerThreads
and the maxIoThreads attributes to the maximum number of threads
for the process for each CPU. For example, if this value is 25 on a
single-processor server, ASP.NET uses the run-time application programming interfaces (APIs) to set the process limit
to 25. On a two-processor server, the limit is set to 50.
Note Monitor the CPU usage when you increase a thread pool to
maintain the limits.
On the File menu, point to New, and then click Project.
Click Visual Basic Projects or Visual C# Projects under Project Types, and then click Console
Application under Templates.
Replace the code in the Class1 code window with the
following code, depending on your project type:
Visual C# .NET Code
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Net.Sockets;
namespace threadTest
{
class Class1
{
public static void Main()
{
// Set number of threads to be created for testing.
int testThreads = 55;
for(int i=0;i<testThreads;i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(PoolFunc));
}
Console.ReadLine();
}
static void PoolFunc(object state)
{
int workerThreads,completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads,
out completionPortThreads);
Console.WriteLine("WorkerThreads: {0}, CompletionPortThreads: {1}",
workerThreads, completionPortThreads);
Thread.Sleep(10000);
string url ="http://www.msn.com";
HttpWebRequest myHttpWebRequest ;
HttpWebResponse myHttpWebResponse=null ;
// Creates an HttpWebRequest for the specified URL.
myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest, and waits for a response.
myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
myHttpWebResponse.Close();
}
}
}
Visual Basic .NET Code
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Threading
Imports System.Net.Sockets
Module Module1
Sub Main()
'Set number of threads to be created for testing.
Dim testThreads As Integer = 55
Dim i As Integer
For i = 0 To testThreads
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf PoolFunc))
Next
Console.ReadLine()
End Sub
Public Sub PoolFunc(ByVal state As Object)
Dim workerThreads, completionPortThreads As Integer
ThreadPool.GetAvailableThreads(workerThreads, completionPortThreads)
Console.WriteLine("WorkerThreads: {0}, CompletionPortThreads: {1}", workerThreads, completionPortThreads)
Thread.Sleep(10000)
Dim url As String = "http://www.msn.com"
Dim myHttpWebRequest As HttpWebRequest
Dim myHttpWebResponse As HttpWebResponse = Nothing
' Creates an HttpWebRequest for the specified URL.
myHttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
'Sends the HttpWebRequest, and waits for a response.
myHttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
myHttpWebResponse.Close()
End Sub
End Module
On the Debug menu, click
Start to run the application. After the available
WorkerThreads reaches 0, you receive the error message that is listed in the "Symptoms" section.