1/**//*ISAPIRuntime的方法,处理请求的入口。*/ 2public int ProcessRequest(IntPtr ecb, int iWRType) 3{ 4 try 5 { 6 /**//*这里ecb被作为参数传入,返回一个HttpWorkerRequest类型的对象,作为对一个请求的数据的封装。但HttpWorkerRequest 7 *只是一个抽象基类,CreateWorkerRequest作为一个工厂方法,返回的实际类型是ISAPIWorkerRequestInProc, 8 *ISAPIWorkerRequestInProcForIIS6或ISAPIWorkerRequestOutOfProc。这些类型里面提供的方法,其实大多 9 *围绕着如何从ecb中去获取数据,所以都包含了很多对System.Web.UnsafeNativeMethods类型中静态方法的调用。 10 **/ 11 HttpWorkerRequest wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, iWRType); 12 string appPathTranslated = wr.GetAppPathTranslated(); 13 string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal; 14 if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal)) 15 { 16 /**//*从这里开始,对请求的处理流程就交给了HttpRuntime。需要注意的是,ISAPI是多线程的,而且对ProcessRequest的调用是异步的, 17 *这就要求HttpRuntime.ProcessRequest方法是线程安全的。看一看HttpRuntime.ProcessRequestNoDemand里的代码大家就清楚, 18 *所有的请求会被排成一个队列,顺次执行,保证了并发安全。 19 *最终,HttpRuntime.ProcessRequestInternal方法会被调用,我们接下来就去看看那个方法。 20 **/ 21 HttpRuntime.ProcessRequestNoDemand(wr); 22 return 0; 23 } 24 HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated })); 25 } 26 catch (Exception exception) 27 { 28 Misc.ReportUnhandledException(exception, new string[] { SR.GetString("Failed_to_process_request") }); 29 throw; 30 } 31 return 1; 32} |
1/**//*在HttpRuntime.ProcessRequestInternal()方法里,有如下几个重要的对象被创建出来: 2 *(1)HttpContext(包括其中的HttpRequest,HttpResponse) 3 *(2)HttpApplication 4 *同时,会执行HttpApplication对象的ProcessRequest方法, 5 */ 6private void ProcessRequestInternal(HttpWorkerRequest wr) 7{ 8 /**//*HttpContext对象在这里被创建。HttpWorkerRequest做为构造参数,而HttpWorkerRequest本身 9 *又围绕着对ecb的处理建立了一群高层的方法,它的实例会被HttpContext传给HttpRequest和HttpResponese 10 *做为他们的构造参数。所以,这里也能更清楚地看出HttpWorkerRequest作为ecb的托管环境封装器的实质。 11 *另外,这里也能清楚地反映出,每一个请求都有一个自己的HttpContext对象(而每一个Htt瀀?潳楬?pContext对象都管理着 12 *一个HttpSession对象--参见HttpContext的Session属性,这也就保证了每个访问者有自己的session对象。),你可以 13 *使用HttpContext.Current来访问到这个对象。 14 */ 15 HttpContext extraData = new HttpContext(wr, false); 16 wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, extraData); 17 Interlocked.Increment(ref this._activeRequestCount); 18 HostingEnvironment.IncrementBusyCount(); 19 try 20 { 21 try 22 { 23 this.EnsureFirstRequestInit(extraData); 24 } 25 catch 26 { 27 if (!extraData.Request.IsDebuggingRequest) 28 { 29 throw; 30 } 31 } 32 extraData.Response.InitResponseWriter(); 33 /**//*用应用程序工厂返回一个HttpApplication对象。 34 *和线程池对线程的管理相似,HttpApplicationFactory中以stack维护了一个HttpApplication的列表(参见HttpApplicationFactory 35 *的_freeList变量)。在这句方法调用的最后,实际是调用了 _theApplicationFactory.GetNormalApplicationInstance(context), 36 *里面就是从_freeList的栈顶pop出一个已经构造的HttpApplication实例。 37 *所以,对于每一个请求,由HttpContext作为上下文,由一个HttpApplication对象来控制整个应用处理的pipeline,整个 38 *处理过程是在由工作进程管理的线程池中的某个线程内完成的。 39 *另外,在一个应用程序域内,由于可以同时处理多个请求,所以就有多个HttpApplication实例和多个活动线程(您可以使用windbg的sos 40 *扩展来观察它们之间的关系,本文就不继续深入了)。 41 *还有,对所有HttpModules的加载就是发生在HttpApplication对象的创建过程之中(包括系统已经提供的Authentication等模块儿和我们 42 *的自定义模块)。我们可以在Web.config里声明自己的自定义模块。这些模块的作用就是在整个HttpApplication处理管线的相关事件点上, 43 *挂上自己的处理。注意一下IHttpModule接口的Init()方法的声明,这个方法的传入参数就是要被创建的HttpApplication对象,所以,如果 44 *你自己的模块想在缓存读取上加入一些自定义操作,你只需进行如下处理即可: 45 public class YourCustomModule : IHttpModule 46 { 47 public void Init(HttpApplication application) 48 { 49 application.ResolveRequestCache += new EventHandler(this.YourCustomResolveRequestCache); 50 } 51 } 52 *另外,通过对HttpApplicationFactory.GetApplicationInstance方法内部实现方式的阅读,你会发现在每一个HttpApplication对象被创建 53 *之后,会立刻调用这个对象的InitInternal方法,而这个方法里面做了很多重要的初始化操作,内容较多,我们将在下文中单独介绍。 54 * 55 */ 56 IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(extraData); 57 if (applicationInstance == null) 58 { 59 throw new HttpException(SR.GetString("Unable_create_app_object")); 60 } 61 if (EtwTrace.IsTraceEnabled(5, 1)) 62 { 63 EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, extraData.WorkerRequest, applicationInstance.GetType().FullName, "Start"); 64 } 65 /**//*看一下System.Web.HttpApplication的类型声明 66 *public class HttpApplication : IHttpAsyncHandler, IHttpHandler, IComponent, IDisposable 67 *你会发现它同时实现了同步和异步的IHandler,所以在默认情况下,ASP.NET对请求的处理是异步的。 68 */ 69 if (applicationInstance is IHttpAsyncHandler) 70 { 71 IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance; 72 alt="" src="/imagelist/2007/236/b2dc295wopin.gif" align=top> extraData.AsyncAppHandler = handler2; 73 /**//*BeginProcessRequest会调用HttpApplication的ResumeSteps()方法,在ResumeSteps()中完成了整个应用程序周期的所有操作, 74 *包括对所有事件的触发、执行,对Handler的调用等。后文会有专门的小节进行介绍。*/ 75 handler2.BeginProcessRequest(extraData, this._handlerCompletionCallback, extraData); 76 } 77 else 78 { 79 applicationInstance.ProcessRequest(extraData); 80 this.FinishRequest(extraData.WorkerRequest, extraData, null); 81 } 82 } 83 catch (Exception exception) 84 { 85 extraData.Response.InitResponseWriter(); 86 this.FinishRequest(wr, extraData, exception); 87 } 88} |
Page page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page), context, true, true) as Page; |
internal interface IExecutionStep { // 每一个“执行步骤”的执行命令 void Execute(); // Properties bool CompletedSynchronously { get; } bool IsCancellable { get; } } |
public void Init(HttpApplication application) { application.BeginRequest += new EventHandler(this.YourCustomMethodForBeginRequestEvent); } |
1this.CreateEventExecutionSteps(EventBeginRequest, steps); 2this.CreateEventExecutionSteps(EventAuthenticateRequest, steps); 3this.CreateEventExecutionSteps(EventDefaultAuthentication, steps); 4this.CreateEventExecutionSteps(EventPostAuthenticateRequest, steps); 5this.CreateEventExecutionSteps(EventAuthorizeRequest, steps); 6this.CreateEventExecutionSteps(EventPostAuthorizeRequest, steps); 7this.CreateEventExecutionSteps(EventResolveRequestCache, steps); 8this.CreateEventExecutionSteps(EventPostResolveRequestCache, steps); 9steps.Add(new MapHandlerExecutionStep(this)); 10this.CreateEventExecutionSteps(EventPostMapRequestHandler, steps); 11this.CreateEventExecutionSteps(EventAcquireRequestState, steps); 12this.CreateEventExecutionSteps(EventPostAcquireRequestState, steps); 13this.CreateEventExecutionSteps(EventPreRequestHandlerExecute, steps); 14steps.Add(new CallHandlerExecutionStep(this));//从这里,您可以很容易看到Handler对页面的解蚊 15 //有哪些应用程序事件在它之前,哪些在它之后 16this.CreateEventExecutionSteps(EventPostRequestHandlerExecute, steps); 17this.CreateEventExecutionSteps(EventReleaseRequestState, steps); 18this.CreateEventExecutionSteps(EventPostReleaseRequestState, steps); 19steps.Add(new CallFilterExecutionStep(this)); 20this.CreateEventExecutionSteps(EventUpdateRequestCache, steps); 21this.CreateEventExecutionSteps(EventPostUpdateRequestCache, steps); 22this._endRequestStepIndex = steps.Count; 23this.CreateEventExecutionSteps(EventEndRequest, steps); 24steps.Add(new NoopExecutionStep()); 25this._execSteps = new IExecutionStep[steps.Count]; 26steps.CopyTo(this._execSteps);//把整个数组拷贝给HttpApplication的私有变量_execSteps |