Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

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


View products that this article applies to.

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

↑ Back to the top


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.

↑ Back to the top


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:
    1. Open the Machine.config file from the %Systemroot%\Microsoft.NET\Framework\Version\CONFIG folder.
    2. 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.
    3. Save the changes to the Machine.config file.

↑ Back to the top


Status

This behavior is by design.

↑ Back to the top


More information

  1. Start Microsoft Visual Studio .NET.
  2. On the File menu, point to New, and then click Project.
  3. Click Visual Basic Projects or Visual C# Projects under Project Types, and then click Console Application under Templates.
  4. 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
  5. 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.

↑ Back to the top


References

For more information, visit the following Microsoft Web sites:

↑ Back to the top


Keywords: kbnamespace, kbweb, kbwnet, kberrmsg, kbconfig, kbdev, kbthread, kbprb, kbxml, KB815637

↑ Back to the top

Article Info
Article ID : 815637
Revision : 5
Created on : 5/13/2007
Published on : 5/13/2007
Exists online : False
Views : 409