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

This article has been archived. It is offered "as is" and will no longer be updated.
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:
    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.
This behavior is by design.
  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 ="";         						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.IOImports System.NetImports System.TextImports System.ThreadingImports System.Net.SocketsModule 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 = ""      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 SubEnd 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.
For more information, visit the following Microsoft Web sites:

Article ID: 815637 - Last Review: 02/27/2014 21:17:42 - Revision: 1.4

Microsoft ASP.NET 1.0, Microsoft ASP.NET 1.1

  • kbnosurvey kbarchive kbnamespace kbweb kbxml kbwnet kberrmsg kbconfig kbdev kbthread kbprb KB815637