Microsoft KB Archive/815637

= PRB: System.InvalidOperationException Error When You Use HttpWebRequest and HttpWebResponse Classes in Application with Thread Pool =

Article ID: 815637

Article Last Modified on 5/13/2007

-

APPLIES TO


 * Microsoft ASP.NET 1.0
 * Microsoft ASP.NET 1.1

-



SYMPTOMS
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



CAUSE
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.



WORKAROUND
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 \Microsoft.NET\Framework\ \CONFIG folder.
 * In the  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.
 * Save the changes to the Machine.config file.



STATUS
This behavior is by design.



MORE INFORMATION
 Start Microsoft Visual Studio .NET. 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(&quot;WorkerThreads: {0}, CompletionPortThreads: {1}&quot;,            workerThreads, completionPortThreads); Thread.Sleep(10000); string url =&quot;http://www.msn.com&quot;; 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(&quot;WorkerThreads: {0}, CompletionPortThreads: {1}&quot;, workerThreads, completionPortThreads) Thread.Sleep(10000) Dim url As String = &quot;http://www.msn.com&quot; 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 &quot;Symptoms&quot; section.</li></ol>

<div class="references_section">