|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
HttpWebRequest ThreadPool usage - strange behaviourno answer, I'll repost it here. I you think that there is even more appropriate group for this, please let me know, and I'll repost. Thanks. <Repost> Hi, I read a lot of articles about deadlocks and ThreadPool overloading when a lot of WebService or WebRequests are made from and ASP.NET applications. In most of these articles and examples there is a statement, that HttpWebRequest.GetResponse() call is always executed asyncronously in v. 1.x of the network. I used Reflector to examine this, and indeed, the code looks like: BeginGetRequest(...); ....... EndGetRequest(); Now, I created a test console application, which invokes a simple web service. This service only invokes Thread.Sleep for the number of seconds passed as parameter. Note - this is for .Net v.1.1 SP1. My test application starts 3 threads (not from the threadpool). The first one prints on console the current ThreadPool free threads. And the other 2 make invocation of the sample web service (not using a proxy, but pure GET request, using HttpWebRequest class), requesting delays of 10 and 20 seconds. Now, the strange thing is, that I do not see any thread of the ThreadPool used while waiting for the HttpResponse, I.e. this behaves very differently from what I read so far about how HttpRequests are made. I tried to invoke HttpWebRequest in 3 different ways (just comment and uncomment the corresponding 2 lines in the Main method): 1. A custom thread just invokes the synchronous GetResponse method - no threadpool usage is visible, even as per the articles I mentioned, it should translate in async invocation internally. 2. A threadpool thread invokes synchronous GetResponse - then obviously a threads from the pool are used, but only the ones, which make the call, but still not visible another threadpool thread which is used by the GetResponse. 3. A custom thread, which invokes async GetResponse (with BeginGetResponse/EndGetResponse), as well as async reading of the response stream. Still I can not see a threadpool thread to be used. Can somebody explain this behaviour? Why this sample works not like it should be? If all these articles are wrong, should I worry if I have a async web service, which internally invokes a 100-200 HttpRequests per invocation. I may have more than 300 invocations of that service in the same time? Actually, what I'm after is a web service, which will be used by more than 300 clients at the same time, which by itself retrieves 100-200 web pages per request. I want to speedup the process, and to use all available resources to fetch as many pages as possible at a time using threads. At the following URL you can find a zip with the source files I used. You need to set your IIS virtual directory to map to the test web service: http://216.17.90.93/ThreadTest.zip These are the articles I read on the topic: <http://msdn.microsoft.com/msdnmag/issues/04/12/NETMatters/> <http://www.deez.info/sengelha/blog/2005/03/03/beware-threadpools-and- httpwebrequest/> <http://msdn.microsoft.com/library/default.asp?url=/library/en- us/dnservice/html/service07222003.asp> <http://msdn.microsoft.com/msdnmag/issues/03/06/Threading/> Cheers Sunny Hi Sunny,
Currently you are trying to track how the GetResponse in .NET 1.1. running. You wondering it is not using the ThreadPool threads by checking the GetAvailableThreads method. Based on my research, the interval 1000 to check the GetAvailableThreads is too large, you may try to use the approach below to check you will find that the value will change. private static void DisplayStatus() { while (true) { int worker; int conn; ThreadPool.GetAvailableThreads(out worker, out conn); if(worker!=25 || conn!=1000) Console.WriteLine("{0}: Available: Worker: {1}, conn: {2}", DateTime.Now, worker, conn); Thread.Sleep(0); } } By default, the worker = 25 and conn = 1000, but the method above will display the value when the worker is not 25 and the conn is not 1000. Actually in the article you mentioned, the GetResponse method internally will check the available thread in the threadpool, note, this is a internal method. internal static bool IsThreadPoolLow() { int num1; int num2; if (ComNetOS.IsAspNetServer) { return false; } ThreadPool.GetAvailableThreads(out num1, out num2); if ((num1 >= 2) && (!ComNetOS.IsWinNt || (num2 >= 2))) { return false; } return true; } So I think you do not need to check at by yourself. Also in .NET 2.0 the problem is fixed, because the GetResponse will no long running asynchronously. Actually I did not suggest you running too many threads in one process, this is why CLR internally suggest the worker threads to be 25. Because actually it is the CPU to run the code, even if we have many threads, but if there is only one CPU, actually there will be only one thread running in the same time. Best regards, Peter Huang Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Peter,
Now I can see what happens. I added a delay (10 secs) in the callback function, and then I could see that IO threadpool threads are used. But then, still all these articles are wrong in terms that they always speak about the 25 per processor limitation, while it uses the IO threads. I tried on different machines, and while the regular threadpool thread (the 25 per processor ones) do increase based on the number of processors, the IO threads are always 1000, so they do not depend on the number of processors. It is strange that this is not discussed anywhere. Is there any article/documentation, etc., which explains which framework methods use which part of the threadpool? Looks like an async delegate invocation uses the first part (25 per processor). But what threadpool is used with remoting, or by async web services, etc.? What threads are going to be used if I implement async HTTP handler, as described in these articles? Cheers Sunny Hi Sunny,
Based on my research, I did not find such a document about the .NET method implementation concerned of ThreadPool. But generally as you said, if we use async delegate invoke, it should be on Worker thread, we can considered all the IO related operation(socket/network, file...) on the IO Threads. The HttpWebRequest will call into Socket related network method, we also considered them as IO threads. But the other non IO related should be on the worker t hreads. Also the design on the ThreadPool should be used to help the developer to control/manage the thread schedule, the dev should not care its implement, if you want to control over more detailed information, it would better create/manage thread ourself, but not ThreadPool. We could simply query the GetAvailableThreads to know if the ThreadPool is busy, if no, we just put the job into ThreadPool and wait for return. Best regards, Peter Huang Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||