"There is not enough free thread in the ThreadPool object to complete the operation" phenomenon and solution
Written by: Zheng @ultrapower 20050406
In fact, Microsoft has an "asynchronous HttpWebRequest, interface implementation and other" to explain this phenomenon is very clear, I just make a note here.
The most common is when using HttpWebRequest, this error occurs when the Send method is invoked because:
Because the dotnet ThreadPool provides 25 free thread/cpu (which can be modified in Machine.config), the InvalidOperationException exception is reported when it is used, and the exception prompts:
System.InvalidOperationException:There were not enough free threads in the ThreadPool object to complete the operation |
That's what Stephen Toub of Microsoft said:
The first thing to know is that HttpWebRequest never makes a sync request in the Microsoft.NET Framework version 1.x. What do I mean by saying so? Let's take a look at the code written for HttpWebRequest.GetResponse in the Shared source CLI (SSCLI), where the code shown omits to see the code that previously retrieved the response and the code that calculated the timeout:
public override WebResponse GetResponse () {
IAsyncResult asyncresult = BeginGetResponse (null, NULL);
Return EndGetResponse (asyncresult);
}
As you can see, HttpWebRequest.GetResponse is just begingetresponse and EndGetResponse on the surrounding packaging. They are run asynchronously, which means that begingetresponse the thread from which the actual HTTP request is made differs from the thread that invoked it, and endgetresponse blocks until the request completes. The actual result of this is that HttpWebRequest the ThreadPool of each outbound request into the work item queue. Therefore, we know that HttpWebRequest uses threads from ThreadPool.
As an alternative solution to the problem, the Framework team implements the exception that you are studying. At the end of the BeginGetResponse (just before the work item is queued), use System.Net.Connection.IsThreadPoolLow to query how many worker threads are available in the pool. If the number is too small (less than 2), InvalidOperationException will be raised.
The good news is that in the. NET Framework 2.0, synchronization requests made with HttpWebRequest.GetResponse are truly synchronized, so that the problem ceases to exist, allowing you to include methods that invoke GetResponse in your core content. The bad news is that you'll still be bothered by this problem in the 1.x version. One solution is (as you pointed out) to explicitly limit the number of work items that have been queued or the number of work items that are executed in ThreadPool at any time. To implement this approach, you need a way to track how many unfinished work items are currently available, and to block new requests before reaching the predetermined boundaries.
So we can judge the current number of free threads:
int WT; int ct; int count=0; while (true) { if (count++>20) Break Threadpool.getavailablethreads (out Wt,out CT); if (wt<5) { Thread.Sleep (1000); Continue } Else Break } |
In addition to this HttpWebRequest problem, this problem can occur elsewhere.
In http://support.microsoft.com/default.aspx?scid=kb;en-us;815637
Microsoft has demonstrated the following programs:
using System; using System.IO; using System.Net; using System.Text; using System.Threading; using System.Net.Sockets; namespace threadpoolexception { |