999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

ASP.NET運(yùn)行時(shí)模型的源碼解析

2008-12-31 00:00:00張家琴
電腦知識(shí)與技術(shù) 2008年33期

摘要:ASP.NET是微軟公司推出的基于DotNet平臺(tái)的網(wǎng)絡(luò)開發(fā)技術(shù),對(duì)B/S模式應(yīng)用的開發(fā)提供了強(qiáng)大的支持,該文從源代碼級(jí)別進(jìn)入ASP.NET底層,分析ASP.NET運(yùn)行時(shí)模型,揭開ASP.NET應(yīng)用程序運(yùn)行的幕后細(xì)節(jié)。

關(guān)鍵詞:ASP.NET;DotNet平臺(tái);網(wǎng)絡(luò)開發(fā);B/S模式應(yīng)用;運(yùn)行時(shí)模型

中圖分類號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)33-1415-04

SourceCode Analyzing for ASP.NET Runtime Model

ZHANG Jia-qing

(Fujian Institude of Economics Management, Fuzhou 350002, China)

Abstract: Based on DotNet platform, Microsoft Proposed the network developing technology called ASP.NET which provides strong support to the development of B/S pattern application programs. This paper enters into the bottom of ASP.NET from the level of source code so as to analyze the runtime model of ASP.NET, so that running details behind the curtain of ASP.NET application programs are uncovered.

Key words: ASP.NET; DotNet platform; network developing; B/S pattern application; runtime model

1 引言

ASP.NET運(yùn)行時(shí)模型指的是ASP.NET 框架在接收到客戶端請(qǐng)求,到獲取合適的HttpHandler接管請(qǐng)求之間,以及從HttpHandlers生成處理結(jié)果到發(fā)送處理結(jié)果給客戶端之間,ASP.NET 框架所完成的一系列工作和處理邏輯[1]。本文將通過源代碼級(jí)別的分析,深入討論ASP.NET 2.0運(yùn)行時(shí)模型,解析ASP.NET應(yīng)用程序運(yùn)行時(shí)模型的工作原理。

2 ISAPI接口標(biāo)準(zhǔn)與IIS服務(wù)器的可擴(kuò)展性

IIS服務(wù)器是部署ASP.NET應(yīng)用的標(biāo)準(zhǔn)Web服務(wù)器,由于IIS服務(wù)器在設(shè)計(jì)時(shí)引入了開放的ISAPI接口標(biāo)準(zhǔn),具備極高的可擴(kuò)展性,在核心組件不變的情況下可靈活支持不同類型不同版本的應(yīng)用,例如IIS 5.1版能夠同時(shí)支持ASP.NET 1.0、1.1、2.0,甚至可以支持部署基于DotNetFramework 3.5的ASP.NET應(yīng)用程序。ISAPI的全稱是:Internet Server Application Programming Interface,即Internet服務(wù)器應(yīng)用編程接口,它為開發(fā)人員提供了強(qiáng)大的可編程能力,只要按照標(biāo)準(zhǔn)接口開發(fā)不同類型Web應(yīng)用程序的ISAPI擴(kuò)展程序,就能實(shí)現(xiàn)對(duì)IIS功能上的擴(kuò)展,從而使IIS可以處理不同類型的客戶端請(qǐng)求,例如讓IIS處理Perl或PHP應(yīng)用程序[2]。

IIS管理器提供了應(yīng)用程序配置功能,可以對(duì)不同的客戶端請(qǐng)求配置不同的ISAPI擴(kuò)展程序。ISAPI擴(kuò)展程序通常以DLL的形式存在,可以被IIS加載并調(diào)用。在ASP.NET2.0下,對(duì)應(yīng)于.aspx的ASP.NET應(yīng)用程序,其ISAPI擴(kuò)展程序默認(rèn)情況下位于C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\目錄下,以aspnet_isapi.dll(下文簡稱aspnet_isapi)文件的形式存在[3]。

有了ISAPI擴(kuò)展,IIS服務(wù)器就可以根據(jù)客戶端請(qǐng)求的資源擴(kuò)展名,來決定應(yīng)由哪個(gè)ISAPI擴(kuò)展來處理客戶端請(qǐng)求,然后就可以將請(qǐng)求轉(zhuǎn)發(fā)給合適的ISAPI擴(kuò)展。例如當(dāng)訪問資源的擴(kuò)展名為.aspx、.ascx、.ashx 和 .asmx時(shí),IIS服務(wù)器會(huì)自動(dòng)將請(qǐng)求轉(zhuǎn)發(fā)給缺省情況下位于C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\目錄下aspnet_isapi.dll進(jìn)行處理[4],這個(gè)動(dòng)態(tài)庫就是一個(gè)ISAPI擴(kuò)展程序,負(fù)責(zé)處理ASP.NET應(yīng)用程序的請(qǐng)求。

3 ASP.NET的后臺(tái)輔助進(jìn)程aspnet_wp.exe

實(shí)際上客戶發(fā)起的請(qǐng)求最終要由aspnet_isapi傳遞給它背后的aspnet_wp.exe去處理,.Net平臺(tái)將其稱為ASP.NET Worker Process(下文簡稱WP),該文件位于.NET framework安裝目錄下,與aspnet_isapi.dll所在位置相同。

當(dāng)aspnet_isapi接收到IIS轉(zhuǎn)發(fā)的ASP.NET請(qǐng)求后,會(huì)將請(qǐng)求放入隊(duì)列,并根據(jù)實(shí)際情況分配請(qǐng)求處理任務(wù)給WP進(jìn)程,一旦請(qǐng)求被轉(zhuǎn)送給WP進(jìn)程,WP進(jìn)程便會(huì)通知aspnet_isapi,請(qǐng)求正在被處理。這個(gè)通知的過程是通過同步I/0完成的,這么實(shí)現(xiàn)目的是為了保證處理過程的完整性,因?yàn)橹挥挟?dāng)請(qǐng)求在aspnet_isapi內(nèi)部被標(biāo)記為“executing”后,WP才會(huì)真正開始處理該請(qǐng)求。此后請(qǐng)求便在WP的上下文環(huán)境中執(zhí)行,當(dāng)執(zhí)行結(jié)束后,處理結(jié)果會(huì)通過一個(gè)異步的開放管道回送給aspnet_isapi,這時(shí)請(qǐng)求的狀態(tài)會(huì)被更新為“Done”,接著請(qǐng)求就會(huì)從隊(duì)列中清除。如果WP進(jìn)程崩潰,所有正在處理中的請(qǐng)求,都將維持“executing”狀態(tài)一段時(shí)間,等到aspnet_isapi檢測(cè)到WP進(jìn)程死掉后,會(huì)自動(dòng)丟棄所有的請(qǐng)求,并釋放已經(jīng)分配的資源[5]。其過程如圖1所示。

WP會(huì)分析每一個(gè)請(qǐng)求的信息,解析出其中的虛擬目錄信息,并檢查該虛擬目錄對(duì)應(yīng)的AppDomain是否已經(jīng)存在,如果不存在則創(chuàng)建一個(gè)新的AppDomain,然后使用它,否則直接重用已經(jīng)建立的AppDomain對(duì)象。這里的AppDomain指的是.NET中引入的應(yīng)用程序域的概念,它可以理解為一個(gè)進(jìn)程或一個(gè)邊界,或一個(gè)容器,它是應(yīng)用程序的執(zhí)行環(huán)境,.NET下所有的應(yīng)用程序都運(yùn)行在AppDomain中,每一個(gè)ASP.NET應(yīng)用程序(IIS中的站點(diǎn)或者虛擬目錄)都會(huì)有一個(gè)AppDomain與之對(duì)應(yīng)[6],它保存了Applcation對(duì)象、Cache等全局變量。

4 請(qǐng)求在ASP.NET運(yùn)行時(shí)中的處理,步驟一:ISAPIRuntime->HttpRuntime

WP接收到aspnet_isapi轉(zhuǎn)發(fā)的請(qǐng)求后,就將請(qǐng)求轉(zhuǎn)送給指定虛擬目錄對(duì)應(yīng)的AppDomain中的ISAPIRuntime對(duì)象,由它完成對(duì)aspnet_isapi封裝后的請(qǐng)求包的解析工作,筆者使用Lutz Roeder's .NET Reflector工具查看System.Web.Dll,通過分析ISAPIRuntime的源碼發(fā)現(xiàn),客戶的請(qǐng)求首先會(huì)被該類的ProcessRequest方法處理,該方法的部分代碼如下:

ISAPIWorkerRequest wr = 1;

try{

bool useOOP = iWRType == 1;

wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);

wr.Initialize();

……

if (……){

HttpRuntime.ProcessRequestNoDemand(wr);

return 0;

}

……

}

可以看出在ProcessRequest方法中,主要通過調(diào)用一些非托管代碼生成HttpWorkerRequest對(duì)象,在上述代碼中,對(duì)應(yīng)于wr對(duì)象(ISAPIWorkerRequest類型繼承自HttpWorkerRequest類),該對(duì)象包含當(dāng)前請(qǐng)求的所有信息,然后ISAPIRuntime調(diào)用HttpRuntime的ProcessRequestNoDemand方法傳遞創(chuàng)建好的HttpWorkerRequest對(duì)象,這個(gè)方法的代碼如下:

internal static void ProcessRequestNoDemand(HttpWorkerRequest wr){

RequestQueue queue = _theRuntime._requestQueue;

if (queue != 1){

wr = queue.GetRequestToExecute(wr);

}

if (wr != 1){

CalculateWaitTimeAndUpdatePerfCounter(wr);

wr.ResetStartTime();

ProcessRequestNow(wr);

}

}

該方法先從請(qǐng)求隊(duì)列中取出一個(gè)請(qǐng)求,然后更新請(qǐng)求的引用計(jì)數(shù)器等信息,接著就讓ProcessRequestNow方法處理請(qǐng)求,這個(gè)方法的代碼如下:

internal static void ProcessRequestNow(HttpWorkerRequest wr){

_theRuntime.ProcessRequestInternal(wr);

}

追蹤分析源碼可以發(fā)現(xiàn)_theRuntime對(duì)象是在HttpRuntime內(nèi)部定義的,其類型就是HttpRuntime自身,它在HttpRuntime的靜態(tài)構(gòu)造函數(shù)中被初始化。

5 請(qǐng)求在ASP.NET運(yùn)行時(shí)中的處理,步驟二:HttpRuntime.ProcessRequestInternal()

接下來我們重點(diǎn)分析HttpRuntime類ProcessRequestInternal方法的運(yùn)作細(xì)節(jié)!使用Reflector工具追蹤至ProcessRequestInternal方法的內(nèi)部:

HttpContext context;

context = new HttpContext(wr, 1);

……

this.EnsureFirstRequestInit(context);

context.Response.InitResponseWriter();

……

IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);

……

IHttpAsyncHandler handler2 = (IHttpAsyncHandler)applicationInstance;

context.AsyncAppHandler = handler2;

handler2.BeginProcessRequest(context,this._handlerCompletionCallback, context);

……

通過分析該方法的源碼,發(fā)現(xiàn)它主要完成如下處理:

1) 根據(jù)HttpWorkerRequest對(duì)象初始化HttpContext對(duì)象,它包含了request、response等屬性,在編程中經(jīng)常會(huì)用到這些重要的屬性來完成特定的任務(wù)。

2) 調(diào)用EnsureFirstRequestInit方法完成第一次請(qǐng)求的初始化工作,該方法鎖定全局變量_beforeFirstRequest,然后調(diào)用FirstRequestInit(context)完成應(yīng)用程序配置文件的加載、初始化請(qǐng)求隊(duì)列、裝載Bin目錄下的所有程序集等工作,然后更新_beforeFirstRequest為1。

3) 執(zhí)行InitResponseWriter創(chuàng)建HttpWriter對(duì)象,用于寫入處理結(jié)果返回信息。

4) 調(diào)用HttpApplicationFactory類的GetApplicationInstance方法來生成IHttpHandler(這里生成的是一個(gè)默認(rèn)的HttpApplication對(duì)象,HttpApplication實(shí)現(xiàn)了IHttpHandler接口)。

5) 調(diào)用HttpApplication對(duì)象(它同時(shí)實(shí)現(xiàn)了IHttpAsyncHandler接口)的BeginProcessRequest方法執(zhí)行客戶請(qǐng)求。

需要注意的是,筆者在跟蹤至HttpApplicationFactory類的GetApplicationInstance方法內(nèi)部時(shí)發(fā)現(xiàn)它最終通過調(diào)用該類的GetNormalApplicationInstance方法獲取HttpApplication實(shí)例:

return _theApplicationFactory.GetNormalApplicationInstance(context);

再深入一步,進(jìn)入GetNormalApplicationInstance方法內(nèi)部,我們終于看到HttpApplication對(duì)象是如何被創(chuàng)建和初始化的:

HttpApplication application = 1;

……

application = (HttpApplication)HttpRuntime.CreateNonPublicInstance(this._theApplicationType);

using (new ApplicationImpersonationContext()){

application.InitInternal(context, this._state, this._eventHandlerMethods);

}

我們發(fā)現(xiàn)HttpApplication類提供了一個(gè)名為InitInternal的方法,調(diào)用方通過它來完成HttpApplication實(shí)例的初始化工作,在這個(gè)方法的內(nèi)部,有如下代碼:

……

this.InitModules();

……

this.HookupEventHandlersForApplicationAndModules(handlers);

……

this._stepManager = new ApplicationStepManager(this);

this._stepManager.BuildSteps(this._resumeStepsWaitCallback);

……

可以看到在HttpApplication對(duì)象初始化時(shí),首先會(huì)自動(dòng)調(diào)用自身的InitModules方法來加載在web.config文件中配置的所有HttpModule模塊。接著HookupEventHandlersForApplicationAndModules方法被調(diào)用,這個(gè)方法完成global.asax文件中配置的HttpApplication或HttpModule事件的綁定。最后ApplicationStepManager對(duì)象的BuildSteps方法被調(diào)用,完成HttpApplication事件的綁定,這個(gè)方法很重要,它將創(chuàng)建各種HttpApplication.IExecutionStep對(duì)象并保存到一個(gè)數(shù)組列表中,以便在BeginProcessRequest方法內(nèi)部調(diào)用ResumeSteps方法依次執(zhí)行這些對(duì)象的Execute()方法,完成各種處理。

圖2是以上分析的一個(gè)總結(jié)。

圖1 請(qǐng)求傳遞和處理過程圖

圖2請(qǐng)求在ASP.NET運(yùn)行時(shí)內(nèi)部處理過程圖

在取得HttpApplication對(duì)象實(shí)例之后,HttpRuntime對(duì)象開始調(diào)用它的BeginProcessRequest方法(實(shí)現(xiàn)IHttpAsyncHandler接口中定義的方法)處理請(qǐng)求:

IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData){

……

this._stepManager.InitRequest();

this._context.Root();

HttpAsyncResult result = new HttpAsyncResult(cb, extraData);

this.AsyncResult = result;

……

this.ResumeSteps(1);

return result;

}

該方法首先調(diào)用ApplicationStepManager對(duì)象的InitRequest方法完成一些初始化工作,例如將記錄當(dāng)前執(zhí)行步驟的變量清0、置請(qǐng)求處理完成標(biāo)志為1等。然后根據(jù)上下文創(chuàng)建HttpAsyncResult對(duì)象記錄執(zhí)行結(jié)果,最后ResumeSteps方法被調(diào)用!這個(gè)方法會(huì)依次取出在數(shù)組列表中的HttpApplication.IExecutionStep對(duì)象,傳遞給HttpApplication的ExecuteStep方法,由它調(diào)用執(zhí)行IExecutionStep對(duì)象的Execute()方法。當(dāng)執(zhí)行到MapHandlerExecutionStep時(shí),會(huì)執(zhí)行如下代碼獲取最終執(zhí)行請(qǐng)求的HttpHandler:

context.Handler = this._application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, 1);

HttpApplication對(duì)象的MapHttpHandler方法將根據(jù)配置文件結(jié)合請(qǐng)求類型和URL,以調(diào)用相應(yīng)的IHttpHandlerFactory來獲取HttpHandler對(duì)象,例如與.aspx頁面對(duì)應(yīng)的Page類就是一種HttpHandler。此后請(qǐng)求處理的執(zhí)行權(quán)被轉(zhuǎn)交至對(duì)應(yīng)的HttpHandler對(duì)象上。至此,本文通過源代碼分析技術(shù),詳細(xì)解析了ASP.NET應(yīng)用程序在底層的運(yùn)作細(xì)節(jié),限于篇幅,無法繼續(xù)深入討論ASP.NET頁面的編譯及執(zhí)行過程。

6 結(jié)語

ASP.NET運(yùn)行時(shí)是整個(gè)ASP.NET技術(shù)框架中最為復(fù)雜、最難以理解,但卻十分重要的部分,對(duì)ASP.NET 2.0運(yùn)行時(shí)源代碼的研究有助于我們加深對(duì)ASP.NET 技術(shù)的理解,將為我們開發(fā)ASP.NET 2.0應(yīng)用程序帶來很多幫助。

參考文獻(xiàn):

[1] 譚振林.道不遠(yuǎn)人—深入解析ASP.NET 2.0 控件開發(fā)[M].北京:電子工業(yè)出版社,2007:15-18.

[2] Dr Khosravi S.Professional IIS 7 and ASP.NET Integrated Programming[M].北京:JOHN WILEY SONS INC,2005:8-9.

[3] 奚江華.圣殿祭司的ASP.NET 2.0開發(fā)詳解——使用C#[M].2版.北京:電子工業(yè)出版社,2008:49-51.

[4] Mitchell S,Walther S.ASP.NET權(quán)威指南[M].湯濤,譯.北京:中國電力出版社,2003:551-553.

[5] Esposito D.The ASP.NET HTTP Runtime[EB/OL].[2003-07-10].http://msdn.microsoft.com/en-us/library/aa479328.aspx.

[6] Evjen B,Hanselman S,Muhammad F.ASP.NET 2.0 高級(jí)編程[M].李敏波,譯.4版.北京:清華大學(xué)出版社,2006:371-373.

主站蜘蛛池模板: 极品国产在线| 日韩欧美中文字幕在线精品| 国产精品视频公开费视频| 欧美人人干| 国产中文一区a级毛片视频| 亚洲国产成人久久精品软件| 午夜福利网址| 97在线国产视频| 午夜一区二区三区| 亚洲毛片网站| 亚洲欧美日韩中文字幕一区二区三区| 99re这里只有国产中文精品国产精品| 嫩草影院在线观看精品视频| 天堂成人av| 91小视频在线观看免费版高清| 国产精品va免费视频| 国产成+人+综合+亚洲欧美| a欧美在线| 日本欧美成人免费| 美女国内精品自产拍在线播放| 18禁影院亚洲专区| 欧美狠狠干| 国产91九色在线播放| 亚洲成a人在线播放www| 干中文字幕| 99精品在线看| 久久综合亚洲鲁鲁九月天| 一级爱做片免费观看久久| 天堂网亚洲系列亚洲系列| 久久综合九九亚洲一区| 日韩欧美国产成人| 毛片免费在线| 国产本道久久一区二区三区| 99久久国产综合精品2020| 玩两个丰满老熟女久久网| 国产精品夜夜嗨视频免费视频| 国产日韩精品欧美一区喷| 久久香蕉国产线看观看式| 久久福利片| 亚洲va视频| 国产精品伦视频观看免费| 日韩亚洲高清一区二区| 国产杨幂丝袜av在线播放| 国产精品 欧美激情 在线播放| 91在线高清视频| 日韩在线第三页| 久久精品66| 婷婷激情亚洲| 欧美成人影院亚洲综合图| 国产乱子伦精品视频| 婷婷六月综合| 亚洲日本中文综合在线| 日韩中文无码av超清| 有专无码视频| 久久91精品牛牛| 高清久久精品亚洲日韩Av| 在线观看亚洲国产| 亚洲免费毛片| 亚洲永久色| 欧美 亚洲 日韩 国产| 国产精品性| 精品国产免费观看| 国产视频你懂得| 韩国v欧美v亚洲v日本v| 欧美第二区| 欧美性猛交一区二区三区| 日韩无码黄色网站| 午夜视频免费一区二区在线看| 免费一级毛片在线播放傲雪网| 黄色成年视频| 日韩无码视频网站| 91香蕉视频下载网站| 国产在线观看精品| 老司国产精品视频91| 亚洲人成影视在线观看| 日韩美毛片| 尤物在线观看乱码| 国模沟沟一区二区三区| 亚洲一欧洲中文字幕在线| 男女猛烈无遮挡午夜视频| 无码aaa视频| 国产精品专区第1页|