top
Loading...
ASP.NET底層架構探索之再談.NET運行時
在這里我們有一個在ISAPI擴展中活動的,可調用的ISAPIRuntime對象的實例。每次運行時是啟動的并運行著的時候(譯注:相對的,如果運行時并沒有啟動,就需要象上一章所說的那樣載入運行時),ISAPI的代碼調用ISAPIRuntime.ProcessRequest()方法,這個方法是真正的進入ASP.NET管道的入口,這個流程在圖4中顯示。

記住ISAPI是多線程的,所以請求也會通過AppDomainFactory.Create()(譯注:原文為ApplicationDomainFactory,疑有誤)函數中返回的引用在多線程環境中被處理.列表1顯示了ISAPIRuntime.ProcessRequest()方法中反編譯后的代碼,這個方法接收一個ISAPI ecb對象和服務類型(WorkerRequestType)作為參數.這個方法是線程安全的,所以多個ISAPI線程可以同時在這一個被返回的對象實例上安全的調用這個方法。

列表1:ProcessRequest方法接收一個ISAPI Ecb并將其傳給工作線程

public int ProcessRequest(IntPtr ecb, int iWRType)
{
HttpWorkerRequest request1 = ISAPIWorkerRequest.CreateWorkerRequest(ecb, iWRType);
string text1 = request1.GetAppPathTranslated();
string text2 = HttpRuntime.AppDomainAppPathInternal;
if (((text2 == null) || text1.Equals(".")) ||
(string.Compare(text1, text2, true, CultureInfo.InvariantCulture) == 0))
{
HttpRuntime.ProcessRequest(request1);
return 0;
}
HttpRuntime.ShutdownAppDomain("Physical application path changed from " +text2 + " to " + text1);
return 1;
}

這里實際的代碼并不重要,記住這是從內部框架代碼中反編譯出來的,你不能直接處理它,它也有可能在將來發生改變.它只是用來揭示在幕后發生了什么.ProcessRequest方法接收非托管的ECB引用并將它傳送給ISAPIWorkerRequest對象,此對象負責為當前請求創建創建請求上下文.在列表2中顯示了這個過程.

System.Web.Hosting.ISAPIWorkerRequest類是HttpWorkerRequest類的一個抽象子類(譯注:HttpWorkerRequest和ISAPIWorkerRequest都是抽象類,并且ISAPIWorkerRequest繼承自HttpWorkerRequest),它的工作是構建一個作為Web應用輸入的輸入輸出的抽象視角。注意這里有另一個工廠方法:CreateWorkerRequest,通過判斷接受到的第二個參數來創建對應的WorkerRequest對象.有三個不同的版本:ISAPIWorkerRequestInProc,ISAPIWorkerRequestInProcForIIS6,ISAPIWorkerRequestOutOfProc.每次有請求進入,這個對象被創建并作為請求和響應對象的基礎,它會接收它們的數據和由WorkerRequest提供的數據流.

抽象的HttpWorkerRequest類在低層接口上提供一個高層的抽象,這樣就封裝了數據是從哪里來的,可以是一個CGI Web服務器,Web瀏覽器控件或者是一些你用來給HTTP運行時”喂”數據的自定義的機制.關鍵是ASP.NET能用統一的方法來接收信息。

在使用IIS的情況下,這個抽象是建立在ISAPI ECB塊周圍.在我們的請求處理過程中,ISAPIWorkerRequest掛起ISAPI ECB并根據需要從它那里取出信息.列表2顯示了請求字符串值(query string value)是如何被取出來的.

列表2:使用非托管數據的ISAPIWorkerRequest方法

// *** Implemented in ISAPIWorkerRequest

public override byte[] GetQueryStringRawBytes()
{
byte[] buffer1 = new byte[this._queryStringLength];
if (this._queryStringLength > 0)
{
int num1 = this.GetQueryStringRawBytesCore(buffer1, this._queryStringLength);
if (num1 != 1)
{
throw new HttpException( "Cannot_get_query_string_bytes");
}
}
return buffer1;
}
// *** Implemented in a specific implementation class ISAPIWorkerRequestInProcIIS6

internal override int GetQueryStringCore(int encode,StringBuilder buffer, int size)
{
if (this._ecb == IntPtr.Zero)
{
return 0;
}
return UnsafeNativeMethods.EcbGetQueryString(this._ecb,encode,buffer,size);
}

ISAPIWorkerRequest實現了一個高層次的包裝方法,它調用了低層的核心方法,負責真正的訪問非托管APIs-或稱為”服務級別的實現”(service level implementation).這些核心方法在特殊的ISAPIWorkerRequest子類中為它寄宿的環境提供特殊的實現,這實現了簡單的擴展的(pluggable)環境,這樣一來當以后新的Web服務器接口或其他平臺成為了ASP.NET的目標時附加的實現類可以在被簡單的提供出來。這里還有一個協助類(helper class)System.Web.UnsafeNativeMethods.里面許多對ISAPI ECB結構的操作實現了對ISAPI擴展的非托管操作。
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗