Thread Pool in ISS Question

  • Thread starter Thread starter Bill
  • Start date Start date
B

Bill

If running a .Net application under IIS with 50 simultaneous requests and
each request is trying to use an ASYNC socket what happens to the thread
pool for that application? It appears that there is a maximum of 50 worker
threads in the pool, if all those 50 threads are processing requests how
will the new ASYNC threads get created? Won't this cause a deadlock while
waiting for an free thread, which never occurs?

Can someone explain to me how this works?
 
Bill said:
If running a .Net application under IIS with 50 simultaneous requests and
each request is trying to use an ASYNC socket what happens to the thread
pool for that application? It appears that there is a maximum of 50 worker
threads in the pool, if all those 50 threads are processing requests how
will the new ASYNC threads get created? Won't this cause a deadlock while
waiting for an free thread, which never occurs?

Can someone explain to me how this works?

There is only one .net ThreadPool per process. So you will want to keep your
hands off the thread pool when running under ASP.NET. Since the thread pool
is a process-level resource you need to be very careful using it in any
multi-appdomain situation. But this is especially so in ASP.NET since the
thread pool provides the ASP.NET worker threads whick handle the user
requests.

That means no async io, no BeginInvoke and no QueueUserWorkItem.

You are free to start a thread to do a background job, or even build your
own thread pool to handle long-running tasks.

David
 
As I understand it, you are quite correct. IIS hosts it's own copy of the CLR (which handles the threadpool.) Each copy of the CLR has one ThreadPool, of which there is 25 worker threads per CPU. These worker threads are used by application, async requests, and internally by the CLR. If every one of these worker threads are in use, any additional requests (from any source) will go onto a queue and awaits a return of a thread to the pool. It the items that are processing on the threads are not real short, you may end up noticing a delay in processing.

Now, the CLR and MOST async calls are over very quickly, so you would have to seriously overload the system to see problems if those are the only onces running from the ThreadPool. If on the other hand, you are using the ThreadPool explicatly or from an async call that you KNOW will be long running, then you can run into problems.

What I have done in the past when handling this type of problem is to create my own thread in the Async call. That thread then does the work, while returning the async thread to the pool.

HTH
 
Let me tell you the situation that is giving me a problem. Currently the
Socket functions like Connect() and GetHostByName() do not have timeout
values that can be set. So in order to have a valid timeout value I need to
use the ASYNC version so that it can be manually canceled. Is there anyway
to get around using ASYNC calls but still have the ability to control the
timeout? I am noticing after so many concurrent connection attempts they
start failing because (I think) there are no more threads available to
process the request.


Bill
 
Bill said:
Let me tell you the situation that is giving me a problem. Currently the
Socket functions like Connect() and GetHostByName() do not have timeout
values that can be set. So in order to have a valid timeout value I need to
use the ASYNC version so that it can be manually canceled. Is there anyway
to get around using ASYNC calls but still have the ability to control the
timeout? I am noticing after so many concurrent connection attempts they
start failing because (I think) there are no more threads available to
process the request.

I believe that Socket.BeginConnect will use blocking socket, callback
function and a worker thread from the .net thread pool.

But winsock has non-blocking sockets, which is a different story. I believe
that you can make a non-blocking connect using a non-blocking socket and
poll the result. I've never done it, but the functionality is there.

David
 
Hi all,

Now, the CLR and MOST async calls are over very quickly, so you would have
to seriously overload the system to see problems if those are the only onces
running from the ThreadPool. If on the other hand, you are using the
ThreadPool explicatly or from an async call that you KNOW will be long
running, then you can run into problems.

David's right on this one. One thing I'd point out, though, is that it is
possible to shoot oneself in the foot, though (I've managed it once or twice
;). Be careful of doing async calls from threads already running in the
pool, since that can easily lead to a deadlock situation in which you
saturate the pool in such a way there's no way to move on...
 
in any case - the top and bottom of all of this is that anyone can bring a
web server to its knees. there is one threadpool for any number of
appdomains in one process. that is a serious issue for hosting. that
aside - the threadpool is extremely useful for scaling which is why it is
implemented the way it is by microsoft. they did tests to show that 1000
applications could be run inside one process - albeit not as efficiently as
they would have liked. the downside is - that other peoples code can stop
your application. that is pretty silly.
 
Hi Jason,
in any case - the top and bottom of all of this is that anyone can bring a
web server to its knees. there is one threadpool for any number of
appdomains in one process. that is a serious issue for hosting. that
aside - the threadpool is extremely useful for scaling which is why it is
implemented the way it is by microsoft. they did tests to show that 1000
applications could be run inside one process - albeit not as efficiently as
they would have liked. the downside is - that other peoples code can stop
your application. that is pretty silly.

Well, it is an risk that will exist in any multithreading implementation!
 
hi Tomas,

to answer your post: not really- that risk was alleviated by the concept of
the process. the appdomain is different - and now runs the risk stated.
 
If anyone has an example using nonblocking sockets in .Net with proper
timeout's and cleanup implemented I would appreciate seeing it.

Thanks.
 
Hi Jason,
to answer your post: not really- that risk was alleviated by the concept of
the process. the appdomain is different - and now runs the risk stated.

Ahh, true, but I thought we were discussing multithreading, not the whole
concept in general.

That said, you are true, and the issue spans far more than just
multithreading... cross-appdomain memory access comes to mind as another.
THis is one of the issues why Windows 2000 is such a poor platform for
ASP.NET hosting scenarios. It takes IIS 6.0' AppPools to make this right
again...
 
agreed :)

Tomas Restrepo (MVP) said:
Hi Jason,


Ahh, true, but I thought we were discussing multithreading, not the whole
concept in general.

That said, you are true, and the issue spans far more than just
multithreading... cross-appdomain memory access comes to mind as another.
THis is one of the issues why Windows 2000 is such a poor platform for
ASP.NET hosting scenarios. It takes IIS 6.0' AppPools to make this right
again...
 
What about GetHostByName() there is no nonblocking call for this. How do
you control the timeout under IIS without using BeginGetHostByName?
 
Back
Top