How exactly does AsyncController
avoid using an ASP.NET worker thread? If I use the event-based pattern (pseudo-code):
[AsyncTimeout(60000)]
public void WaitForWakeUp()
{
AsyncManager.OutstandingOperations.Increase();
EventRaisedElsewhere +=
state =>
{
AsyncManager.OutstandingOperations.Decrease();
return Content("Woke up because of " + state);
};
}
...then according to Clay Lenharts it doesn't use an ASP.NET worke开发者_运维知识库r thread. How is this possible?
I looked a bit into the AsyncController
source code but didn't understand anything, except that it uses IAsyncResult
alot and does QueueUserWorkItem
in some places.
But how can BeginInvoke
and QueueUserWorkItem
not use an ASP.NET worker thread? Surely both of these use a thread pool thread, and surely there is only one thread pool in an ASP.NET worker process?
According to MSDN,
The Web server gets a thread from the thread pool (the worker thread) and schedules it to handle an incoming request. This worker thread initiates an asynchronous operation.
The worker thread is returned to the thread pool to service another Web request.
When the asynchronous operation is complete, it notifies ASP.NET.
But for anything non-trivial, it sounds like initiates an asynchronous operation will still require a thread to run on. Only in extremely simple cases (like using the BCL to download web content) will it be completely unwound and/or completely IOCP bound, right?
I'm asking partly because I see all these Chat Servers implemented using AsyncController
and if all they do is "wait for new messages" I don't understand how that can be done on a non-threadpool thread.
You are sort of correct. It does use a asp.net thread to initiate the async call, but that thread gets finished with & returned to the pool. The async process then runs on another thread from the the worker thread pool before notifying asp.net it need a thread to deal with the result.
it's more efficient because the asp.net thread pool limits incoming connections, so freeing these up as soon as possible allows you to deal with more incoming connections quicker.
At least that's how I see it.
Edit I don't think that's entirely true. There is is only one background thread pool, as defined in the framework, but you can create as many other threads as you like and create your own thread pool, distinct from the background thread pool.
I believe that's what's happening here. There is a small number of worker threads dealing with requests. These worker threads spawn threads in the background pool to deal with the async requests.
Simon
精彩评论