26

I've been told that ASP.NET is multithreaded by default in IIS. How is this threading achieved?

Does the server farm send different requests to different cores?

Does a single request make use of multiple cores?

More importantly, are there any advantages to adding threads to ASP.NET code if the threading is done higher up in IIS?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Craig Warren
  • 1,655
  • 4
  • 23
  • 38

4 Answers4

25

Not only does the server farm different requests to different threads, but a single request can change thread during the course of life cycle. This is called thread agility. I'm looking for a good article explaining it...

EDIT: No definitive articles yet, but one blog post explaining some of the difficulties.

EDIT: More links from comments:

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    But one request does not run at more than one thread at a any given time, so at the end of the day the whole request handling can be viewed as single-threaded. (Or not?) – Tomalak Mar 18 '09 at 10:47
  • 1
    @Tomalak: No, it can't be regarded as single-threaded, because it can change thread. That means if you stick things in a [ThreadStatic] variable at the start of the request, it may not be there at the end of the request. – Jon Skeet Mar 18 '09 at 10:49
  • @Jon I guess this complicates the idea of spawning other thread from within a request even further, doesn't it? – sharptooth Mar 18 '09 at 10:53
  • 1
    What would prompt the thread context to switch? using the IHttpAsyncHandler is explicit in regard to the thread switch. Wasn't aware of another context – Andrew Harry Mar 18 '09 at 10:57
  • @Harry: I believe it happens if some part of the request (or perhaps another request) is taking a long time. Unfortunately details are incredibly sketchy :( – Jon Skeet Mar 18 '09 at 11:00
  • @Tomalak: Asynchronous Page processing can start on one thread and complete on a different thread, for example. – Kev Mar 18 '09 at 11:00
  • @Kev - This would be fairly obvious to anyone implementing the pattern. And it is really a edge case as most people shy away from the complexity of understanding the APM model – Andrew Harry Mar 18 '09 at 11:09
  • @Jon: As far as I am aware, unless you are explicit about you intentions, i.e. using a) Async Pages or b) async method calls (for example to call web services, ASP.NET will run a single page request end to end on the same thread. This is why you can encounter thread pool exhaustion and... – Kev Mar 18 '09 at 11:09
  • perf issues if your page requests are heavily I/O bound. – Kev Mar 18 '09 at 11:10
  • Here's another article about the topic: http://www.lhotka.net/WeBlog/PermaLink,guid,019e3c37-38ed-492e-b769-16e1a57fed0a.aspx I also recently did two questions concerning the same problem here on SO: – Vilx- Mar 18 '09 at 11:23
  • http://stackoverflow.com/questions/536596/ http://stackoverflow.com/questions/585206/ – Vilx- Mar 18 '09 at 11:24
  • 1
    @Kev: I'm pretty sure I've seen it on synchronous pages. Some early lifecycle events happen on one thread, and then the main processing happens on another. I can't remember how I provoked it, exactly. – Jon Skeet Mar 18 '09 at 11:37
  • I think the agility can regard how requests start on iis request handling threads, and then get handed to an asp.net worker thread, only if no worker threads are ready, the request thread will take the thread to a point in the request life cycle, and leave it waiting for a worker thread to complete. – meandmycode Mar 18 '09 at 11:41
  • @meandmycode: That sounds eminently feasible. Do you have any handy links for that? – Jon Skeet Mar 18 '09 at 11:57
  • Hi Jon, it was a long time ago I read regarding this, but I did manage to find a msdn blog talking about the threading differences in IIS6 and IIS7 http://blogs.msdn.com/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx – meandmycode Mar 18 '09 at 15:42
  • @meandmycode: Thanks for that. I'll add it to the list of links. – Jon Skeet Mar 18 '09 at 16:54
9

ASP.net uses the .Net threadpool (which is configurable) Each request is received by one of the threads in the threadpool, until each thread is already occupied. Then requests queue at the IIS Stack, until this also spills over. From there new requests are meet with the very ugly 'Server is unavailable' message.

This is the usual 'multi-threading' story for a ASP.net website.

There are many ways to ensure scalability. The most obvious being performance testing and removing bottlenecks from your code.

ASP.net can really take advantage of multiple cores by utilizing the I/O threads for any I/O request. It makes for ugly code but fast has never been pretty.

Here is the definitive MSDN MAG post on how to do this

UPDATE

Well I probably attempt to answer your full question:

"More importantly is there any advantage to adding threads to ASP.Net code if the threading is done higher up in IIS?"

The short answer is: It depends! If you are waiting on a long running process, then you would be better advised to implement a nicer experience for the requesting client (i.e. Out of band AJAX calls)

if you have multiple independent tasks that need to be completed for the requesting client: then you might be better off spawning a new process to run the tasks in parallel.

If your site gets lots of traffic, then you really need to consider implementing Asynchronous patterns to better utilise your CPU

Andrew Harry
  • 13,773
  • 18
  • 67
  • 102
5

IIS makes use of the multiple cores automatically (although you can turn it off if you so choose).

The advantage to adding threads to ASP.NET code is so that you can control your own application's inner workings and not be forced to rely on IIS to make all the decisions for you.

jpmc26
  • 28,463
  • 14
  • 94
  • 146
TheTXI
  • 37,429
  • 10
  • 86
  • 110
  • Ask a vague question, get a vague answer. The only precise answer possible for the last of the four original questions is "it depends." – Joel Mueller Mar 18 '09 at 21:30
3

A separate thread is usually spawned for each new request, then the operating system does processor scheduling. Unless you need to process just a few requests at a time you don't need extra threading.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • Your answer suggests that a request will stay on the same thread for its whole life, which isn't true (and that assumption can cause issues if you use thread statics). – Jon Skeet Mar 18 '09 at 10:45
  • Well, we never developed programs aware of thread agility, so I had no idea of this previously. – sharptooth Mar 18 '09 at 10:49
  • Doesn't IIS also use a thread pool? Afaik it spawns threads at startup, then reuses them between requests. – Mendelt Mar 18 '09 at 10:56
  • It uses a thread pool, but I focused on the "separate thread for each request" part. – sharptooth Mar 18 '09 at 11:00