明白ECB是怎么回事之后,我们通过Reflector简单了解一下ISAPIRutime的ProcessRequest的实现:
ProcessRequest public int ProcessRequest(IntPtr ecb, int iWRType) { IntPtr zero = IntPtr.Zero; if (iWRType == 2) { zero = ecb; ecb = UnsafeNativeMethods.GetEcb(zero); } ISAPIWorkerRequest wr = null; try { bool useOOP = iWRType == 1; wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP); wr.Initialize(); string appPathTranslated = wr.GetAppPathTranslated(); string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal; if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal)) { HttpRuntime.ProcessRequestNoDemand(wr); return 0; } HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated })); return 1; } catch (Exception exception) { try { WebBaseEvent.RaiseRuntimeError(exception, this); } catch { } if ((wr == null) || (wr.Ecb != IntPtr.Zero)) { throw; } if (zero != IntPtr.Zero) { UnsafeNativeMethods.SetDoneWithSessionCalled(zero); } if (exception is ThreadAbortException) { Thread.ResetAbort(); } return 0; } }
|
对于上面的代码,我觉得没有必要去深究,但是对于那些具有强烈好奇心的朋友除外J。基本上上面的代码完成下面两个任务:
通过传入的ECB和iWRType创建一个叫做ISAPIWorkerRequest的对象:
bool useOOP = iWRType == 1; wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
|
然后调用HttpRuntime.ProcessRequestNoDemand(wr),通过将创建的ISAPIWorkerRequest的对象作为参数传入。
HttpRuntime.ProcessRequestNoDemand的调用真正进入了ASP.NET Runtime Pipeline,这是一个相对复杂的过程。在这里我想简单说说ISAPIWorkerRequest这个重要class,ISAPIWorkerRequest是一个Abstract class,它已通过ECB创建基于当前Request的Context的信息,针对不同的IIS版本,具有不同的ISAPIWorkerRequest subclass,比如:ISAPIWorkerRequestOutOfProc(IIS 5.x), ISAPIWorkerRequestInProcForIIS6, ISAPIWorkerRequestInProcForIIS7。ProcessRequest通过ISAPI传入的iWRType来创建不同HttpWorkerRequest,从而屏蔽了不同IIS的差异,后续的步骤就不需要考虑这种差异了,这是Abstract Factory的典型用法。
【责任编辑:
碧海蓝天 TEL:(010)68476606】
(0票)
(0票)
(0票)
(0票)
(0票)
(0票)