如何:创建异步 HTTP 处理程序
1个回答
展开全部
在异步 HTTP 处理程序的处理期间,ASP.NET 将通常用于外部进程的线程放回线程池中,直到处理程序收到来自外部进程的回调。这样可以避免阻止线程,从而提高性能,因为一次只能执行有限数量的线程。如果许多用户都在请求依赖于外部进程的同步 HTTP 处理程序,那么操作系统可能很快就会用完所有线程,因为大量线程被阻止,正在等待外部进程。下面的代码示例演示了一个异步 HTTP 处理程序,该处理程序在 ASP.NET 应用程序中处理对扩展名为 .SampleAsync 的文件的请求。该示例演示了处理程序的代码,然后演示如何将 .SampleAsync 扩展名映射到 ASP.NET 中的处理程序。最后,该示例演示如何在 IIS 中将 .SampleAsync 扩展名映射到 ASP.NET,以便 IIS 可以将以 .SampleAsync 结尾的请求转发给 ASP.NET。有关ASP.NET 运行库如何与 IIS 交互的更多信息,请参见 ASP.NET 应用程序生命周期概述。创建HelloWorldAsyncHandler HTTP 处理程序类在App_Code 目录中创建一个名为 HelloWorldAsyncHandler 的类,并向类文件中添加以下代码: Visual Basic Imports Microsoft.VisualBasic Imports System.Web Imports System.Threading PublicClass HelloWorldAsyncHandler Implements IHttpAsyncHandler PublicReadOnlyProperty IsReusable() AsBooleanImplements System.Web.IHttpHandler.IsReusable GetReturnFalseEndGetEndPropertyPublicFunction BeginProcessRequest( _ ByVal context As System.Web.HttpContext, _ ByVal cb As System.AsyncCallback, _ ByVal extraData AsObject) _ As System.IAsyncResult _ Implements System.Web.IHttpAsyncHandler.BeginProcessRequest context.Response.Write("<p>Begin IsThreadPoolThread is " _ & Thread.CurrentThread.IsThreadPoolThread & "</p>" & vbCrLf) Dim asynch AsNew AsynchOperation(cb, context, extraData) asynch.StartAsyncWork() Return asynch EndFunctionPublicSub EndProcessRequest(ByVal result As _ System.IAsyncResult) _ Implements System.Web.IHttpAsyncHandler.EndProcessRequest EndSubPublicSub ProcessRequest(ByVal context _ As System.Web.HttpContext) _ Implements System.Web.IHttpHandler.ProcessRequest ThrowNew InvalidOperationException() EndSubEndClassClass AsynchOperation Implements IAsyncResult Private _completed AsBooleanPrivate _state As [Object] Private _callback As AsyncCallback Private _context As HttpContext ReadOnlyProperty IsCompleted() AsBoolean _ Implements IAsyncResult.IsCompleted GetReturn _completed EndGetEndPropertyReadOnlyProperty AsyncWaitHandle() As WaitHandle _ Implements IAsyncResult.AsyncWaitHandle GetReturnNothingEndGetEndPropertyReadOnlyProperty AsyncState() As [Object] _ Implements IAsyncResult.AsyncState GetReturn _state EndGetEndPropertyReadOnlyProperty CompletedSynchronously() AsBoolean _ Implements IAsyncResult.CompletedSynchronously GetReturnFalseEndGetEndPropertyPublicSubNew(ByVal callback As AsyncCallback, _ ByVal context As HttpContext, _ ByVal state As [Object]) _callback = callback _context = context _state = state _completed = FalseEndSubPublicSub StartAsyncWork() ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf StartAsyncTask), Nothing) EndSubPrivateSub 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) EndSub 'StartAsyncTask EndClass 'AsynchOperation C# using System; using System.Web; using System.Threading; class HelloWorldAsyncHandler : IHttpAsyncHandler { publicbool IsReusable { get { returnfalse; } } 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; } publicvoid EndProcessRequest(IAsyncResult result) { } publicvoid ProcessRequest(HttpContext context) { throw new InvalidOperationException(); } } class AsynchOperation : IAsyncResult { privatebool _completed; private Object _state; private AsyncCallback _callback; private HttpContext _context; bool IAsyncResult.IsCompleted { get { return _completed; } } WaitHandle IAsyncResult.AsyncWaitHandle { get { returnnull; } } Object IAsyncResult.AsyncState { get { return _state; } } bool IAsyncResult.CompletedSynchronously { get { returnfalse; } } public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) { _callback = callback; _context = context; _state = state; _completed = false; } publicvoid StartAsyncWork() { ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null); } privatevoid 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); } }该代码实现 BeginProcessRequest 方法。该方法向当前的 HttpContext 对象的 Response 属性中写入一个字符串,创建一个 AsyncOperation 类的新实例,然后调用 StartAsyncWork 方法。然后,StartAsyncWork 方法向 ThreadPool 对象添加 StartAsyncTask 委托。当有线程可用时,将调用 StartAsyncTask 方法,该方法向 Response 属性写出另外一个字符串,然后通过调用 AsyncCallback 委托完成该任务。 注册自定义 HTTP 处理程序在创建了自定义 HTTP 处理程序类之后,必须在 Web.config 文件中注册该类,以便由 ASP.NET 来处理对带有 .SampleAsync 扩展名的文件的请求。在Web.config 文件中注册自定义 HTTP 处理程序如果您的网站没有 Web.config 文件,请创建一个 Web.config 文件。向Web.config 文件添加下面的代码:<configuration> <system.web> <httpHandlers> <add verb="*" path="*.SampleAsync" type="HelloWorldAsyncHandler"/> </httpHandlers> </system.web> </configuration>该代码将 HelloWorldAsyncHandler 处理程序注册为对以 .SampleAsync 结尾的请求的处理程序。为HTTP 处理程序扩展名配置 IISIIS 只将针对某些文件类型的请求传递给 ASP.NET 进行处理。默认情况下,具有 .aspx、.ascx、.asmx 等扩展名的文件已映射到 ASP.NET,但是,如果您希望由 ASP.NET 来处理您所定义的文件扩展名,则必须在 IIS 中注册这些扩展名。有关更多信息,请参见 ASP.NET 应用程序生命周期概述。在IIS 中映射扩展名打开“Internet 服务管理器”。右击您的应用程序,然后选择“属性”。在“目录”选项卡中,单击“配置”。选择“映射”选项卡。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询