ASP. NET How to: create an asynchronous HTTP handler
With the asynchronous HTTP processing program, you can start an external process (for example, a method call to a remote server) and continue the processing of the processing program without waiting for the completion of the external process. During asynchronous HTTP processing, ASP. NET puts the threads typically used for external processes back into the thread pool until the handler receives a callback from the external process. This can avoid blocking threads and improve performance, because only a limited number of threads can be executed at a time. If many users are requesting synchronous HTTP processing programs that depend on external processes, the operating system may soon run out of all threads because a large number of threads are blocked and waiting for external processes.
The following code example demonstrates an asynchronous HTTP processing program that processes requests for files with the extension. sampleasync in an ASP. NET application. This example demonstrates the code of the handler and then how to map the. sampleasync extension to the handler in ASP. NET. Finally, this example shows how to map the. sampleasync extension to ASP. NET in IIS so that IIS can forward requests ending with. sampleasync to ASP. NET.
For more information about how ASP. NET runtime interacts with IIS, see ASP. NET application lifecycle overview.
Create helloworldasynchandler HTTP handler class
Create a directory namedHelloworldasynchandlerAnd add the following code to the class file:
Copy code in Visual BasicImports Microsoft.VisualBasicImports System.WebImports System.ThreadingPublic Class HelloWorldAsyncHandler Implements IHttpAsyncHandler Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable Get Return False End Get End Property Public Function BeginProcessRequest( _ ByVal context As System.Web.HttpContext, _ ByVal cb As System.AsyncCallback, _ ByVal extraData As Object) _ As System.IAsyncResult _ Implements System.Web.IHttpAsyncHandler.BeginProcessRequest context.Response.Write("<p>Begin IsThreadPoolThread is " _ & Thread.CurrentThread.IsThreadPoolThread & "</p>" & vbCrLf) Dim asynch As New AsynchOperation(cb, context, extraData) asynch.StartAsyncWork() Return asynch End Function Public Sub EndProcessRequest(ByVal result As _ System.IAsyncResult) _ Implements System.Web.IHttpAsyncHandler.EndProcessRequest End Sub Public Sub ProcessRequest(ByVal context _ As System.Web.HttpContext) _ Implements System.Web.IHttpHandler.ProcessRequest Throw New InvalidOperationException() End SubEnd ClassClass AsynchOperation Implements IAsyncResult Private _completed As Boolean Private _state As [Object] Private _callback As AsyncCallback Private _context As HttpContext ReadOnly Property IsCompleted() As Boolean _ Implements IAsyncResult.IsCompleted Get Return _completed End Get End Property ReadOnly Property AsyncWaitHandle() As WaitHandle _ Implements IAsyncResult.AsyncWaitHandle Get Return Nothing End Get End Property ReadOnly Property AsyncState() As [Object] _ Implements IAsyncResult.AsyncState Get Return _state End Get End Property ReadOnly Property CompletedSynchronously() As Boolean _ Implements IAsyncResult.CompletedSynchronously Get Return False End Get End Property Public Sub New(ByVal callback As AsyncCallback, _ ByVal context As HttpContext, _ ByVal state As [Object]) _callback = callback _context = context _state = state _completed = False End Sub Public Sub StartAsyncWork() ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf StartAsyncTask), Nothing) End Sub Private Sub StartAsyncTask(ByVal workItemState As [Object]) _context.Response.Write("<p>Completion IsThreadPoolThread is " & Thread.CurrentThread.IsThreadPoolThread & "</p>" & vbCrLf) _context.Response.Write("Hello World from Async Handler!") _completed = True _callback(Me) End Sub 'StartAsyncTaskEnd Class 'AsynchOperation
C # copy codeusing System;using System.Web;using System.Threading;class HelloWorldAsyncHandler : IHttpAsyncHandler{ public bool IsReusable { get { return false; } } public HelloWorldAsyncHandler() { } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>/r/n"); AsynchOperation asynch = new AsynchOperation(cb, context, extraData); asynch.StartAsyncWork(); return asynch; } public void EndProcessRequest(IAsyncResult result) { } public void ProcessRequest(HttpContext context) { throw new InvalidOperationException(); }}class AsynchOperation : IAsyncResult{ private bool _completed; private Object _state; private AsyncCallback _callback; private HttpContext _context; bool IAsyncResult.IsCompleted { get { return _completed; } } WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } } Object IAsyncResult.AsyncState { get { return _state; } } bool IAsyncResult.CompletedSynchronously { get { return false; } } public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) { _callback = callback; _context = context; _state = state; _completed = false; } public void StartAsyncWork() { ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null); } private void StartAsyncTask(Object workItemState) { _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>/r/n"); _context.Response.Write("Hello World from Async Handler!"); _completed = true; _callback(this); }}
This code implements the beginprocessrequest method. This method writes a string to the response attribute of the current httpcontext object and createsAsyncoperationClass, and then callStartasyncworkMethod. Then,StartasyncworkMethod to add a threadpool objectStartasynctaskDelegate. When a thread is availableStartasynctaskMethod.ResponseAttribute, and then the task is completed by calling the asynccallback delegate.
Register a custom HTTP handler
After creating a custom HTTP handler class, you must register the class in the web. config file so that ASP. NET can process requests for files with the. sampleasync extension.
Register a custom HTTP handler in the web. config file
If your website does not have a web. config file, create a web. config file.
Add the following code to the Web. config file:
Copy code<configuration> <system.web> This code willHelloworldasynchandlerThe handler registers as the handler for the request ending with. sampleasync.
Configure IIS for the HTTP handler Extension
IIS only transmits requests for certain file types to ASP. NET for processing. By default. aspx ,. ascx ,. files with extensions such as asmx have been mapped to ASP.. net to process the file extensions you define, you must register these extensions in IIS. For more information, see ASP. NET application lifecycle overview.
Ing extension in IIS
Open Internet Service Manager ".
Right-click your application and select "properties ".
On the "directory" tab, click "Configure ".
Select the ing tab.
Add a new association to map. sampleasync to the aspnet_isapi.dll version to be used.
If you want the handler to run regardless of whether the user requested file name exists, clear the check box "check whether the file exists.
Test a custom HTTP handler
After creating and registering a custom HTTP handler, you can test the handler by requesting resources with the. sampleasync extension in the application.
Test a custom HTTP handler
See