1

Asp.net 2 have 12 threads by default

Now Asp.Net 4 have 5000. We still need async controllers?

Felipe Pessoto
  • 6,855
  • 10
  • 42
  • 73

3 Answers3

6

We still need async controllers?

Yes. Async controllers are useful in situations where you have lengthy operations such as network calls and you don't want to monopolize worker threads for them. The fact that there are 5000 worker threads by default doesn't mean that you have to waste them. Is it because you are a millionaire that you are giving away your money? No.

Obviously if you don't use async controllers correctly they will do more harm than good.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • But Async have a overhead too. It creates a new thread right? I think that 5000 request is more that any server can handle, then why use Async creating more threads and doing more complex code – Felipe Pessoto Jan 31 '11 at 13:30
  • AsyncController doesn't create new threads. They reuse threads from the thread pool. – Darin Dimitrov Jan 31 '11 at 13:45
  • 2
    @Fujiy, the real value of async controllers is when you have lengthy operations such as database calls or web service calls. You could start the request on a thread from the thread pool and then run one or more lengthy operations using IO Completion Ports (IOCP) and once they finish use another thread from the pool to finish the request and render the response. The great advantage is that while those lengthy operations are running you are not monopolizing a thread from the thread pool. Here's an article which provides more details: http://msdn.microsoft.com/en-us/magazine/cc163725.aspx – Darin Dimitrov Jan 31 '11 at 15:51
  • This article says another thing: "That thread calls base.ProcessRequest, causing the page to undergo its normal request-processing lifecycle (complete with events such as Load and Render) but on a non-threadpool thread. Meanwhile, BeginProcessRequest returns immediately after launching the new thread, allowing the thread that's executing BeginProcessRequest to return to the thread pool." – Felipe Pessoto Jan 31 '11 at 16:56
  • Expanding on Darin's answer a bit - asynchronous I/O operations (which is what AsyncController is intended for) operate using IOCP, *not* ThreadPool threads. This is important, as each ThreadPool thread has an associated 1 MB stack (plus other overhead), so if you're using 5000 ThreadPool threads, you're automatically losing 5 GB of memory just due to overhead! IOCP continuations have nowhere near as much overhead, so it's possible to juggle greater numbers of them at any given time. – Levi Jan 31 '11 at 18:01
  • Each IOCP thread can handle multiple tasks? Because no make sense dedicate a IOCP thread to a single I/O task – Felipe Pessoto Feb 01 '11 at 11:10
  • @Levi : Are you sure about this 1 MB of overhead per ThreadPool thread? – Andrei Rînea May 18 '11 at 12:19
  • @Andrea - Yes. The Windows OS by default allocates a dedicated 1 MB stack per thread. Remember - ThreadPool threads are pooled and removed when no longer needed - so you're only taking the hit for threads which are currently active. But if you're doing a lot of concurrent CPU-bound work with ThreadPool, you're very rapidly going to start hitting memory issues. This is precisely one of the reasons the C# / VB teams released the Async CTP a few months ago - to try to solve this issue. – Levi May 18 '11 at 16:17
2

MVC 4/Dev11 makes Async controllers more appealing than previous versions. Add to that WebAPI making it easy to create web services. Start of Levi's comments so they won't be missed (under @Darin Dimitrov's excellent answer)

Expanding on Darin's answer a bit - asynchronous I/O operations (which is what AsyncController is intended for) operate using IOCP, not ThreadPool threads. This is important, as each ThreadPool thread has an associated 1 MB stack (plus other overhead), so if you're using 5000 ThreadPool threads, you're automatically losing 5 GB of memory just due to overhead! IOCP continuations have nowhere near as much overhead, so it's possible to juggle greater numbers of them at any given time. ThreadPool threads are pooled and removed when no longer needed - so you're only taking the hit for threads which are currently active. But if you're doing a lot of concurrent CPU-bound work with ThreadPool, you're very rapidly going to start hitting memory issues. This is precisely one of the reasons the C# / VB teams released the Async CTP a few months ago - to try to solve this issue.

Async for Web service often makes sense - see Should my database calls be Asynchronous Part II

For database applications using async operations to reduce the number of blocked threads on the web server is almost always a complete waste of time. A small web server can easily handle way more simultaneous blocking requests than your database back-end can process concurrently. Instead make sure your service calls are cheap at the database, and limit the number of concurrently executing requests to a number that you have tested to work correctly and maximize overall transaction throughput

See Should my database calls be Asynchronous?

RickAndMSFT
  • 20,912
  • 8
  • 60
  • 78
0

4 or 5000, it doesn't matter, it is just a setting. You can set it to 1 billion if you want to, that won't make your application more scalabe. In the end your machine only has 4 cores (or 8 or 2, but not 5000). Always keep in mind that you can only ever have as many threads running at the same time that the number of cores. Every thread you have in excess to your number of cores is just overhead. It will create more context switches, consume CPU and occupy more memory.

IO (database access, web service, file access...) is not taking up any CPU. If you do it synchronously, it will block a thread for the length of the operation. If you have a lengthy operation (5 seconds), and a load of 1,000 request per second, you will be permanently blocking 5,000 threads. So you are already starving the thread pool (with a setting of 5,000). But what is worse is that you will be trashing your maching with context switches. If you do it asynchronously, no thread will be blocked, no resource is taken, and you have no limit on the number of concurrent IO you can do.

Adding more threads in the thread pool is a quick and dirty hack when you can't afford rewriting your application using asynchronous IO. It is not a clean solution.

Flavien
  • 7,497
  • 10
  • 45
  • 52
  • >> f you have a lengthy operation (5 seconds), and a load of 1,000 request per second, -- if you have that, asynch will not magically make your site performant - you need to fix the data access. see [1]: http://blogs.msdn.com/b/rickandy/archive/2011/07/19/should-my-database-calls-be-asynchronous-part-ii.aspx [2]: http://blogs.msdn.com/b/rickandy/archive/2009/11/14/should-my-database-calls-be-asynchronous.aspx – RickAndMSFT Apr 10 '12 at 20:33