这些天看了一些关于ASP.NET底层的文章,受益匪浅。

     为什么要了解这些底层呢?我觉得做为一个喜欢开发ASP.NET程序员,我不们不仅要知道“怎么做”,我们更应该知道“为什么这么做”,这样的我们才能做得更好。这样我们才能把准确的代码放置准确的位置。

     ASP.NET 像一个全自动的洗车房,车开进车房并通过层层洗刷,最后出来一部闪亮的车。

     IIS维护着一个映射表(图1)用来指定:什么样的请求由什么程序来处理该请求,比如说:所请求资源的扩展名为.asp的请求,由"asp.dll" 处理该请求,这个“DLL”文件称为ISAPI扩展程序。

(图1)

     当一个请求从浏览器发出,到达服务器端,IIS收到该请求。IIS根据所请求资源的扩展名,将该请求转交给相应的ISAPI扩展程序来处理。那扩展名为.aspx的请求是怎么样的呢?同样也是由相应的ISAPI处理该请求,也就是aspnet_isapi.dll,但这只是第一站,aspnet_isapi 还要将该请求转交给ASP.NET来处理。如下图(2)。


(图2)

     IIS运行在一个InetInfo.exe的进程中,IIS收到扩展名为.aspx请求后,加载ASP.NET ISAPI---"aspnet_isapi.dll",ASP.NET ISAPI 会启动一个名为"aspnet_wp.exe"的工作进程,“aspnet_wp.exe”启动时会加载CLR、创建appDomain,在创建对appDomain时会实例化一个名为ISAPIRuntime类,ISAPIRuntime是Asp.net与asp.net ISAPI通信的桥梁。IIS与ASP.NET ISAPI都是非托管程序,而ASP.NET  HttpRuntime则是一个托管程序,ASP.NET ISAPI 通过COM的方式与ASP.NET Http Runtime基于命名管道通信。ISAPIRuntime是一个特殊的类,它实现接口IISAPIRuntime,该接口基于COM。所以说非托管程序可以以COM的方式访问。



[ComImport, Guid("08a2c56f-7c16-41c1-a8be-432917a1a2d1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IISAPIRuntime
{
    
void StartProcessing();
    
void StopProcessing();
    [
return: MarshalAs(UnmanagedType.I4)]
    
int ProcessRequest([In] IntPtr ecb, [In, MarshalAs(UnmanagedType.I4)] int useProcessModel);
    
void DoGCCollect();
}

 

 

 

     ASP.NET ISAPI 调用 ISAPIRumtime  ProcessRequest 方法的,这时就到了托管环境的天下,到ASP.NET发挥的时候了,个个“洗刷”工具开始启动。

 


public int ProcessRequest(IntPtr ecb, int iWRType)
{
    
int num;
    
try
    {
        HttpWorkerRequest wr 
= ISAPIWorkerRequest.CreateWorkerRequest(ecb, iWRType);
        
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 }));
        num 
= 1;
    }
    
catch (Exception exception)
    {
        Misc.ReportUnhandledException(exception, 
new string[] { SR.GetString("Failed_to_process_request") });
        
throw;
    }
    
return num;
}

 

 

 

     ISAPIRuntime将处理权转交给HttpRumtime的ProcessRequestInternal方法

 


private void ProcessRequestInternal(HttpWorkerRequest wr)
{
    HttpContext extraData 
= new HttpContext(wr, false);
    wr.SetEndOfSendNotification(
this._asyncEndOfSendCallback, extraData);
    Interlocked.Increment(
ref this._activeRequestCount);
    HostingEnvironment.IncrementBusyCount();
    
try
    {
        
try
        {
            
this.EnsureFirstRequestInit(extraData);
        }
        
catch
        {
            
if (!extraData.Request.IsDebuggingRequest)
            {
                
throw;
            }
        }
        extraData.Response.InitResponseWriter();
        IHttpHandler applicationInstance 
= HttpApplicationFactory.GetApplicationInstance(extraData);
        
if (applicationInstance == null)
        {
            
throw new HttpException(SR.GetString("Unable_create_app_object"));
        }
        
if (EtwTrace.IsTraceEnabled(51))
        {
            EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, extraData.WorkerRequest, applicationInstance.GetType().FullName, 
"Start");
        }
        
if (applicationInstance is IHttpAsyncHandler)
        {
            IHttpAsyncHandler handler2 
= (IHttpAsyncHandler) applicationInstance;
            extraData.AsyncAppHandler 
= handler2;
            handler2.BeginProcessRequest(extraData, 
this._handlerCompletionCallback, extraData);
        }
        
else
        {
            applicationInstance.ProcessRequest(extraData);
            
this.FinishRequest(extraData.WorkerRequest, extraData, null);
        }
    }
    
catch (Exception exception)
    {
        extraData.Response.InitResponseWriter();
        
this.FinishRequest(wr, extraData, exception);
    }
}
posted on 2009-08-30 21:13  钱途无梁  阅读(1054)  评论(0编辑  收藏  举报