Reputation: 905
HttpTaskAsyncHandler is a nice base-class for making async http-handlers in ASP.NET 4.5 I wonder how the runtime handles more than one await statement in ProcessRequestAsync.
public class CallbackHandler : HttpTaskAsyncHandler
{
public override async Task ProcessRequestAsync(HttpContext context)
{
int value1 = await Task.Factory.StartNew(() => 1);
int value2 = await Task.Factory.StartNew(() => 2);
int value3 = await Task.Factory.StartNew(() => 3);
context.Response.Write(value1 + value2 + value3);
}
public override bool IsReusable
{
get { return true; }
}
}
Is the IIS thread being put on hold 3 times? How do i eventually test/see for this? Is it better to wrap the 3 awaits up in an asyn method?
Edit: I am concerned that this code will take a IIS-workerthread 4 times to handle this request. If i wrap it up in an async method - will it performe better?
This is a diagram explaining the difference between sync and asyn page processing in ASP.NET. I am afraid that my example will result in 3 threads being started from the main worker thread (pink boxes on diagram) and thereby adding overhead.
IIS -> task1 TP -> IIS -> task2 TP -> IIS -> task3 TP -> IIS
(Task switching to the main IIS WT 4 times)
Or is the compiler so smart that it just passes continuation on from one task to the next, and returning to the main thread after the 3 tasks are done.
IIS -> task1 TP -> task2 TP -> task3 TP -> IIS
(Task switching to the main IIS WT 1 time)
Upvotes: 1
Views: 595
Reputation: 457057
It handles it just fine.
In IIS, you have a "request context" provided to your async
handler, and your async
methods by default will resume in that context. Whenever you await
an incomplete task, the thread is returned to the thread pool (it is not blocked), and when that task completes, a thread pool thread is used to continue that async
method after entering that request context.
So, no threads are "held", but the request itself is. Putting multiple await
s in another async
method won't make a difference, but it would make a difference to start multiple Task
s and then wait for them all to complete, e.g., await Task.WhenAll(task1, task2, task3);
(assuming that they are all independent, of course).
I don't know of a good way to verify this behavior.
Upvotes: 1