Reputation: 148524
I saw this aricle which describes implementing the IHttpAsyncHandler
.
Looking at this part:
public class MyAsyncHandler : IHttpAsyncHandler
{
///
/// The queue holds a list of asynchronous results
/// with information about registered sessions
///
public static List<myasyncresult> Queue;
static MyAsyncHandler()
{
// Initialize the queue
Queue = new List<myasyncresult>();
}
public IAsyncResult BeginProcessRequest(HttpContext context,
AsyncCallback cb, object extraData)
{
// Fetch the session id from the request
var sessionId = context.Request["sessionId"];
// Check if the session is already registered
if (Queue.Find(q => q.SessionId == sessionId) != null)
{
var index = Queue.IndexOf(Queue.Find(q => q.SessionId == sessionId));
// The session has already been registered,
// just refresh the HttpContext and the AsyncCallback
Queue[index].Context = context;
Queue[index].Callback = cb;
return Queue[index];
}
// Create a new AsyncResult that holds the information about the session
var asyncResult = new MyAsyncResult(context, cb, sessionId);
// This session has not been registered yet, add it to the queue
Queue.Add(asyncResult);
return asyncResult;
}
public void EndProcessRequest(IAsyncResult result)
{
var rslt = (MyAsyncResult) result;
// send the message to the recipient using
// the recipients HttpContext.Response object
rslt.Context.Response.Write(rslt.Message);
// reset the message object
rslt.Message = string.Empty;
}
}
Where is the asynchronous part here? I dont see any BeginXXX method here.
Also I checked with Thread.CurrentThread.IsThreadPoolThread
at the first line of BeginProcessRequest
and it showed me TRUE
.
So where is the asynchronous part here in this example?
Upvotes: 1
Views: 703
Reputation: 17724
When this handler receives a request, it will call BeginProcessRequest
.
It does not block the calling thread.
When processing is complete it will call EndProcessRequest
.
This will leave your asp.net worker process threads free to serve other requests while this is processing.
When EndProcessRequest
is called, you get to send the processed result back to the client.
Here is a lot of explanation about how asp.net manages threads during an async request lifecycle.
During the lifetime of an asynchronous page, the context starts with just one thread from the ASP.NET thread pool. After the asynchronous requests have started, the context doesn’t include any threads. As the asynchronous requests complete, the thread pool threads executing their completion routines enter the context. These may be the same threads that initiated the requests but more likely would be whatever threads happen to be free at the time the operations complete.
If multiple operations complete at once for the same application, AspNetSynchronizationContext will ensure that they execute one at a time. They may execute on any thread, but that thread will have the identity and culture of the original page.
Some reasoning on when to use async:
Having an async handler is only useful if to process the request you have other async steps available (such as an off-box database call or a long hard drive read that you can call async as well.) To do this properly you would chain async methods (ie BeginProcessRequest would call FileStream.BeginRead with the same (or seperate) callback and handle accordingly.) Refer here: http://msdn.microsoft.com/en-us/library/system.web.ihttpasynchandler.aspx
Take a look at this very detailed explaination on how to use asynchronous handlers
To build a truly effective asynchronous handler, you must spawn an additional thread by hand in response to BeginProcessRequest. There are three important aspects to building a successful asynchronous handler. First, construct a class that supports IAsyncResult to return from BeginProcessRequest. Then, spawn the thread to perform your request processing asynchronously. Finally, notify ASP.NET that you are finished processing the request and are ready to return the response.
To summarize: if you are not creating a processing thread, or waiting for a long time, an async handler won't do much good. When waiting, the request has no threads associated with it. This allows asp.net to scale well even with long waiting tasks.
Upvotes: 2