ASP. NET asynchronous request processing (asynchronous HTTP handlers)

Source: Internet
Author: User

In ASP. NET, You can inherit the ihttphandler interface to implement a synchronous (synchronous) class for processing user requests. For example, if you want to process all requests whose types are fakephp through your HTTP hanlder, You can implement the following classes:

Using system;
Using system. Web;

Public class fakephphttphandler: ihttphandler {
Public void processrequest (httpcontext context ){
// Let's pretend we can handle PHP stuff

Public bool isreusable {
Get {return true ;}

Then you can register your dll as the. fakephp handler in IIS. These are described in the following msdn documents:


Here we will talk about how to implement an asynchronous (asynchronous) d HTTP handler. It's actually easy to say, as long as the ihttpasynchandler interface is implemented.

Ihttpasynchandler has two methods:

Initiates an asynchronous call to the HTTP handler.

Provides an asynchronous process end method when the process ends.

This is obviously consistent with the standard asynchronous programming model (or asynchronous pattern) in. NET Framework:

Reference: asynchronous programming Overview

The advantage of asynchronous mode is ASP. net worker thread will not wait for beginprocessrequest to return, but will turn around to receive other user requests (of course you can also ask worker thread to wait, but this is equivalent to synchronous handler ). It usually takes a long time to process the background of a Web request. Suppose you can only process 10 user requests per second. In synchronization mode, if 11 people access your service at the same time, one person will see error messages such as 500 internal server error. However, in asynchronous mode, worker thread only needs to call beginprocessrequest, and according to asynchronous programming overview, beginprocessrequest should be returned immediately ("immediately" means that it should not perform operations for a long time, instead, call APIs such as queueuserworkitem to put time-consuming tasks in the new thread for execution. In this way, the worker thread can be freed up to receive the next user request.

Note: Asp. the max worker thread ceiling of net can be changed through the maxworkerthreads attribute in the processmodel configuration element (refer to: improving ASP. net Performance and processmodel element), but the maximum value is only 100 (range from 5 to 100, default 20 ).

Naturally, ASP. NET knows how to handle asynchronous operations. There are several options:

1) when you call beginprocessrequest, ASP. NET can input an asynccallback delegate at the same time. After you complete asynchronous operations, you should call this callback function to notify ASP. NET.

2) Asp. net can constantly check the iscompleted attribute of iasyncresult (this is the return value of beginprocessrequest) to check whether the asynchronous operation has been completed. Of course, when you complete the asynchronous operation, you are obligated to set iscompleted to true.

3) ASP. NET can also wait for the asyncwaithandle signal. asyncwaithandle is another property of iasyncresult, which is similar to the waiting on kernel object in the classic Win32 system.

4) ASP. NET can directly call endprocessrequest.

Note: 3) and 4) are the standard blocking execution method specified in asynchronous programming overview. That is to say, if your main thread cannot do any work before the asynchronous operation is completed, it can be completed through 3) or 4.

Theoretically, you should ensure that your ihttpasynchandler can meet all of the above four methods. But in reality, you may not necessarily do this. So what are the requirements that must be met by ASP. NET? Or how does ASP. NET Implement Asynchronous calls and return?

In fact, Asp. net adopts method 1, that is, when calling beignprocessrequest, Asp. net passed in an asynccallback, And you should call this callback after completing the asynchronous operation, and in this asynccallback, Asp. net calls your endprocessrequest again to complete the work.

Based on the above discussion, we can design our asynchronous HTTP hanlder as follows:

Public class asyncfakephphttphandler: ihttpasynchandler
Private void processrequestcallback (object state)
Asyncresult async = (asyncresult) State;
// This is where the real work is done
Processrequest (async. context );
Async. iscompleted = true;
If (null! = Async. asynccallback)
Async. asynccallback (async );
Public iasyncresult beginprocessrequest (httpcontext context, asynccallback, object state)
Asyncresult async = new asyncresult (context, asynccallback, State );
// If the callback is null, we can return immediately and let endprocessrequest do all the job
// If callback is not null, we will use our thread pool to execute the necessary asynchronous operations
// What happens in ASP. NET is that the callback in not null, so queueuserworkitem will be used
If (null! = Async. asynccallback)
Threadpool. queueuserworkitem (processrequestcallback, async );
Return async;
// This design also satisfies Method 4), we implement it this way to follow the asynchronous pattern as much as we can
Public void endprocessrequest (iasyncresult result)
Asyncresult async = (asyncresult) result;
If (null = async. asynccallback)
Processrequest (async. context );

Summarize the key points for implementing asynchronous HTTP handler:

1) all time-consuming operations (such as IO) in beginprocessrequest should adopt asynchronous calls (such as beginread/endread) or generate a new thread for execution. Yes, you can design a blocking beginprocessrequest. No one can stop you from doing this. But that's a bad idea.

2) beginprocessrequest/endprocessrequest is implemented to allow ASP. NET to call your HTTP handler asynchronously.

3) You should create a class that implements the iasyncresult interface. In beginprocessrequest, you will generate an instance of this class and return it to ASP. NET (note the return value type of beginprocessrequest ). According to asynchronous pattern, ASP. NET will send this instance back to you when calling endprocessrequest. You can use this instance to determine the current status of the task you are running.

4) What I personally think is more confusing is the "two-segment" Asynchronous call operation. First, ASP. NET asynchronously calls our HTTP handler through beginprocessrequest/endprocessrequest. Then, in beginprocessrequest, we use the asynchronous mode again (using queueuserworkitem or other begin */end * operations) to complete the real work. In fact, the asynchronous call in the second step is the place where another thread is actually generated to handle the work. ASP. NET calls our beginprocessrequest is only a form of protocol notification, because we told ASP. NET: Hey that I am an asynchronous handler. ASP. NET said: Well, since you said so, I will use your asynchronous interface to call you. In fact, in the httpruntime source code, you can see the ASP. NET operation as follows:

If (APP is ihttpasynchandler ){
// Asynchronous Handler
Ihttpasynchandler asynchandler = (ihttpasynchandler) app;
Context. asyncapphandler = asynchandler;
Asynchandler. beginprocessrequest (context, _ handlercompletioncallback, context );
Else {
// Synchronous Handler
App. processrequest (context );
Finishrequest (context. workerrequest, context, null );

========================================================== ======================================

The last question is about IIS/asp. net is also a very interesting question about request processing workflows. The following article is great (but the author's English Writing kinda sucks ,:)). For example, we can know that the whole process involves two queue, one in the kernel mode and the other in the user mode, and the other in the ASP.. net, and ASP. net worker thread is to get the next request to be processed from this queue.

This article from the csdn blog, reproduced please indicate the source:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.