也許可以有一些思緒 
讓我們再來看下IIS官網上對IIS7的圖解
傳送門 :http://www.iis.net/learn/get-started/introduction-to-iis/introduction-to-iis-architecture

1、當客戶端浏覽器開始 HTTP 請求一個WEB 服務器的資源時,HTTP.sys 攔截到這個請求。
2、HTTP.sys 聯系 WAS 獲取配置信息。
3、WAS 向配置存儲中心(applicationHost.config)請求配置信息。
4、WWW 服務接收到配置信息,配置信息指類似應用程序池配置信息,站點配置信息等等。
5、WWW 服務使用配置信息去配置 HTTP.sys 處理策略。
6、WAS為請求創建一個進程(如果不存在的話)
7、工作者進程處理請求並對HTTP.sys做出響應.
8、客戶端接受到處理結果信息。
IIS 7 應用程序池的托管管道模式(集成模式)華麗的變身

IIS7中對asp.net的請求不再是分兩條處理管道,而是將asp.net和IIS集成起來,這樣做的好處是統一了請求驗證工作,加強了asp.net對於請求的控制能力等等。在IIS7中,asp.net不再像IIS6一樣只限定於aspnet_isapi.dll中,而是被解放出來,從IIS接收到HTTP請求開始,即進入asp.net的控制范圍,asp.net可以存在於一個請求在IIS中各個處理階段。甚至可以為部署在IIS7中的PHP應用提供基於asp.net的驗證身份驗證功能(傳送門:http://msdn.microsoft.com/zh-cn/magazine/cc135973.aspx)。
好吧,戛然而止一下,篇幅有限:IIS部分告一段落 留一些遐想空間.
再來分析ASP.NET的運行機制
在IIS6圖示中我們分析到“ AppManagerAppDomainFactory 的 Create 方法為 Application 創建一個 Application Domain;通過 ISAPIRuntime 的 ProcessRequest 處理 Request,進而將流程進入到 ASP.NET Http Runtime Pipeline。”
下面我們來看一下AppDomain運行過程圖示

AppDomain的作用,相信大家都很了解了吧.這裡簡明扼要的寫幾點:
一個AppDomain中的代碼創建的對象不能由另一個AppDomain中的代碼直接訪問(只能使用按引用封送或者按值封送,起到了很好的隔離作用).
AppDomain可以卸載 CLR不支持從AppDomain中卸載一個程序集的能力,但可以告訴CLR卸載一個AppDomain,從而達到卸載當前包含在該AppDomain內的所有程序集.
AppDomain 可以單獨保護 當宿主加載一些代碼之後,可以保證這些代碼不會被破壞(或讀取)宿主本身使用的一些重要的數據結構.
AppDomain可以單獨配置 設置主要影響CLR在AppDomain中加載程序集的方式,涉及搜索路徑、版本綁定重定向、卷影復制及加載器的優化。
由以上幾點可以看出AppDomain確保了Windows系統及其中運行的應用程序的健壯性。AppDomain提供了保護、配置和終止其中每一個應用程序所需的隔離性。
再來看下ProcessRequest的過程

簡單分析一下上圖
ProcessRequest(HttpWorkerRequest wr)中判斷wr是否為null,然後判斷管線是否完整,再調用ProcessRequestNoDemand(wr)方法,
並判斷當前RequestQueue 是否為null,接著計算等待時間並更新管線數 CalculateWaitTimeAndUpdatePerfCounter(wr);
重置wr開始時間wr.ResetStartTime();調用ProcessRequestNow(wr)方法,並調用ProcessRequestInternal(wr)方法
繼續圖例

ProcessRequestInternal方法如下:
1 private void ProcessRequestInternal(HttpWorkerRequest wr)
2 {
3 HttpContext context;
4 try
5 {
6 context = new HttpContext(wr, false);//由HttpWorkerRequest生成HttpContext
7 }
8 catch
9 {
10
11 //常見的400錯誤,就是在這裡捕捉到滴
12 wr.SendStatus(400, "Bad Request");
13 wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
14 byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
15 wr.SendResponseFromMemory(bytes, bytes.Length);
16 wr.FlushResponse(true);
17 wr.EndOfRequest();
18 return;
19 }
20 wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);
21 Interlocked.Increment(ref this._activeRequestCount);
22 HostingEnvironment.IncrementBusyCount();
23 try
24 {
25 try
26 {
27 this.EnsureFirstRequestInit(context);
28 }
29 catch
30 {
31 if (!context.Request.IsDebuggingRequest)
32 {
33 throw;
34 }
35 }
36 context.Response.InitResponseWriter();
37 IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);
38 //得到HttpApplication
39
40 if (applicationInstance == null)
41 {
42 throw new HttpException(System.Web.SR.GetString("Unable_create_app_object"));
43 }
44 if (EtwTrace.IsTraceEnabled(5, 1))
45 {
46 EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start");
47 }
48 if (applicationInstance is IHttpAsyncHandler)
49 {
50 IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance;
51 context.AsyncAppHandler = handler2;
52 handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context);//屆時 HttpApplication處理請求
53 }
54 else
55 {
56 applicationInstance.ProcessRequest(context);
57 this.FinishRequest(context.WorkerRequest, context, null);
58 }
59 }
60 catch (Exception exception)
61 {
62 context.Response.InitResponseWriter();
63 this.FinishRequest(wr, context, exception);
64 }
65 }
再看下GetApplicationInstance(context) 實例化Application的方法
View Code
最後調用的GetNormalApplicationInstance方法中對當前空閒的application數目進行判斷,調用
application.InitInternal(context, this._state, this._eventHandlerMethods)方法,
this.InitModules()初始化所有的Modules,包含用戶自定義的HttpModules
this._stepManager.BuildSteps(this._resumeStepsWaitCallback);//管道事件序列
貼一下源碼:
1 internal override void BuildSteps(WaitCallback stepCallback)
2 {
3 ArrayList steps = new ArrayList();
4 HttpApplication app = base._application;
5 bool flag = false;
6 UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;
7 flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0);
8 steps.Add(new HttpApplication.ValidatePathExecutionStep(app));
9 if (flag)
10 {
11 steps.Add(new HttpApplication.UrlMappingsExecutionStep(app));
12 }
13 app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);
14 app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps);
15 app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps);
16 app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);
17 app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps);
18 app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);
19 app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);
20 app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);
21 steps.Add(new HttpApplication.MapHandlerExecutionStep(app));
22 app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);
23 app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps);
24 app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps);
25 app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);
26 steps.Add(new HttpApplication.CallHandlerExecutionStep(app));
27 app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);
28 app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);
29 app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);
30 steps.Add(new HttpApplication.CallFilterExecutionStep(app));
31 app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);
32 app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps);
33 this._endRequestStepIndex = steps.Count;
34 app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);
35 steps.Add(new HttpApplication.NoopExecutionStep());
36 this._execSteps = new HttpApplication.IExecutionStep[steps.Count];
37 steps.CopyTo(this._execSteps);
38 this._resumeStepsWaitCallback = stepCallback;
39 }
到這裡想必能夠使大家對ASP.NET管道機制能夠有一個簡單的回顧.當然還有很多地方沒有詳細分析.
再來總結一下IIS運行過程及ASP.NET管道機制:
Request→ (Internet ) HTTP.sys 監聽 → WAS (IIS6 web Admin Service /IIS7 (Windows Activation Service) 接收請求
→(傳入)Application Pool's → w3wp.exe(檢查URL後綴)
→(加載)ISAPI擴展[aspnet_isapi.dll] → 注冊映射
構造HttpRuntime類 →ProcessRequest方法
HttpContext實例產生(Request,Response,Session and so on…)
HttpRuntime 調用 HttpApplicationFactory加載HttpApplication對象
穿越HttpModule到達HttpHandler
簡單用140個字符(即一條微博的字數
)概括:
Request→ (Internet ) HTTP.sys →(WAS)→Application Pool's → w3wp.exe→ISAPI→ Map→ (Pipeline)HttpWorkerRequest→AppDomain→HttpRuntime→ProcessRequest()→ HttpContext(Request,Response)→ HttpRuntime→HttpApplicationFactory→HttpApplication→ HttpModule→HttpHandler→EndRequest
以上為個人學習摘要,如有錯誤,歡迎指正!!
補充
1:剛剛看到dudu發的一個閃存,裡面提到了Application pool 與 AppDomain 的區別 來自stackoverflow,希望對大家有所幫助.
2:WAS縮寫在IIS6中的指的是(Web Admin Service),在IIS7中指的是(Windows Activation Service) 縮寫一樣.這個在寫文章的時候注意到過,但是沒有深入考慮. 理解不是很到位. 暫不妄下斷言. 歡迎斧正!! :-)