今天看了web请求的生命周期,看完了还有些不懂,就是用反编译工具,查看封装内库的内部实现。

从计算机内部查到web.dll,使用反编译工具打开

打开后

  1. public int ProcessRequest(IntPtr ecb, int iWRType)
  2. {
  3. IntPtr intPtr = IntPtr.Zero;
  4. if (iWRType == )
  5. {
  6. intPtr = ecb;
  7. ecb = UnsafeNativeMethods.GetEcb(intPtr);
  8. }
    //首先创建ISAPIWorkerRequest,将请求报文封装在内,调用CreateWorkerRequest方法来实现,
  9. ISAPIWorkerRequest iSAPIWorkerRequest = null;
  10. int result;
  11. try
  12. {
  13. bool useOOP = iWRType == ;
  14. iSAPIWorkerRequest = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
  15. iSAPIWorkerRequest.Initialize();
  16. string appPathTranslated = iSAPIWorkerRequest.GetAppPathTranslated();
  17. string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
  18. if (appDomainAppPathInternal == null || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
  19. {
    //调用ProcessRequestNoDemand方法,并将封装的请求报文传入进去
  20. HttpRuntime.ProcessRequestNoDemand(iSAPIWorkerRequest);
  21. result = ;
  22. }
  23. else
  24. {
  25. HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[]
  26. {
  27. appDomainAppPathInternal,
  28. appPathTranslated
  29. }));
  30. result = ;
  31. }
  32. }
  33. catch (Exception ex)
  34. {
  35. try
  36. {
  37. WebBaseEvent.RaiseRuntimeError(ex, this);
  38. }
  39. catch
  40. {
  41. }
  42. if (iSAPIWorkerRequest == null || !(iSAPIWorkerRequest.Ecb == IntPtr.Zero))
  43. {
  44. throw;
  45. }
  46. if (intPtr != IntPtr.Zero)
  47. {
  48. UnsafeNativeMethods.SetDoneWithSessionCalled(intPtr);
  49. }
  50. if (ex is ThreadAbortException)
  51. {
  52. Thread.ResetAbort();
  53. }
  54. result = ;
  55. }
  56. return result;
  57. }
  1. CreateWorkerRequest内部,根据不同的IIS版本创建不同的对象
  2.  
  3. // System.Web.Hosting.ISAPIWorkerRequest
  4.  
  5. internal static ISAPIWorkerRequest CreateWorkerRequest(IntPtr ecb, bool useOOP)
  1. {
  2. ISAPIWorkerRequest result;
  3. if (useOOP)
  4. {
  5. EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
  6. if (EtwTrace.IsTraceEnabled(, ))
  7. {
  8. EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, false);
  9. }
  10. result = new ISAPIWorkerRequestOutOfProc(ecb);
  11. }
  12. else
  13. {
  14. int num = UnsafeNativeMethods.EcbGetVersion(ecb) >> ;
  15. if (num >= )
  16. {
  17. EtwTrace.TraceEnableCheck(EtwTraceConfigType.IIS7_ISAPI, ecb);
  18. }
  19. else
  20. {
  21. EtwTrace.TraceEnableCheck(EtwTraceConfigType.DOWNLEVEL, IntPtr.Zero);
  22. }
  23. if (EtwTrace.IsTraceEnabled(, ))
  24. {
  25. EtwTrace.Trace(EtwTraceType.ETW_TYPE_APPDOMAIN_ENTER, ecb, Thread.GetDomain().FriendlyName, null, true);
  26. }
  27. if (num >= )
  28. {
  29. result = new ISAPIWorkerRequestInProcForIIS7(ecb);
  30. }
  31. else
  32. {
  33. if (num == )
  34. {
  35. result = new ISAPIWorkerRequestInProcForIIS6(ecb);
  36. }
  37. else
  38. {
  39. result = new ISAPIWorkerRequestInProc(ecb);
  40. }
  41. }
  42. }
  43. return result;
  44. }

进入ProcessRequestNoDemand内部

  1. // System.Web.HttpRuntime
  2. internal static void ProcessRequestNoDemand(HttpWorkerRequest wr)
  3. {
  4. RequestQueue requestQueue = HttpRuntime._theRuntime._requestQueue;
  5. wr.UpdateInitialCounters();
  6. if (requestQueue != null)
  7. {
  8. wr = requestQueue.GetRequestToExecute(wr);
  9. }
  10. if (wr != null)
  11. {
  12. HttpRuntime.CalculateWaitTimeAndUpdatePerfCounter(wr);
  13. wr.ResetStartTime();
    //调用ProcessRequestNow方法,并将封装的请求报文传入
  14. HttpRuntime.ProcessRequestNow(wr);
  15. }
  16. }
  1. // System.Web.HttpRuntime
  2. internal static void ProcessRequestNow(HttpWorkerRequest wr)
  3. {
  4. HttpRuntime._theRuntime.ProcessRequestInternal(wr);
  5. }

进入ProcessRequestInternal方法内部

  1. // System.Web.HttpRuntime
  2. private void ProcessRequestInternal(HttpWorkerRequest wr)
  3. {
  4. Interlocked.Increment(ref this._activeRequestCount);
  5. if (this._disposingHttpRuntime)
  6. {
  7. try
  8. {
  9. wr.SendStatus(, "Server Too Busy");
  10. wr.SendKnownResponseHeader(, "text/html; charset=utf-8");
  11. byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>");
  12. byte[] expr_45 = bytes;
  13. wr.SendResponseFromMemory(expr_45, expr_45.Length);
  14. wr.FlushResponse(true);
  15. wr.EndOfRequest();
  16. }
  17. finally
  18. {
  19. Interlocked.Decrement(ref this._activeRequestCount);
  20. }
  21. return;
  22. }
  23. HttpContext httpContext;
  24. try
  25. {
    //根据请求报文创建HttpContext对象,如果创建出错误就会返回404
    httpContext = new HttpContext(wr, false);
  26. }
  27. catch
  28. {
  29. try
  30. {
  31. wr.SendStatus(, "Bad Request");
  32. wr.SendKnownResponseHeader(, "text/html; charset=utf-8");
  33. byte[] bytes2 = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
  34. byte[] expr_A5 = bytes2;
  35. wr.SendResponseFromMemory(expr_A5, expr_A5.Length);
  36. wr.FlushResponse(true);
  37. wr.EndOfRequest();
  38. return;
  39. }
  40. finally
  41. {
  42. Interlocked.Decrement(ref this._activeRequestCount);
  43. }
  44. }
  45. wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, httpContext);
  46. HostingEnvironment.IncrementBusyCount();
  47. try
  48. {
  49. try
  50. {
    //将第一次请求设置为false
  51. this.EnsureFirstRequestInit(httpContext);
  52. }
  53. catch
  54. {
  55. if (!httpContext.Request.IsDebuggingRequest)
  56. {
  57. throw;
  58. }
  59. }
    //初始化Response
  60. httpContext.Response.InitResponseWriter();
    //根据HttpApplicationFactory创建Application实例
  61. IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(httpContext);
  62. if (applicationInstance == null)
  63. {
  64. throw new HttpException(SR.GetString("Unable_create_app_object"));
  65. }
  66. if (EtwTrace.IsTraceEnabled(, ))
  67. {
  68. EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, httpContext.WorkerRequest, applicationInstance.GetType().FullName, "Start");
  69. }
  70. if (applicationInstance is IHttpAsyncHandler)
  71. {
  72. IHttpAsyncHandler httpAsyncHandler = (IHttpAsyncHandler)applicationInstance;
  73. httpContext.AsyncAppHandler = httpAsyncHandler;
  74. httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext);
  75. }
  76. else
  77. {
  78. applicationInstance.ProcessRequest(httpContext);
  79. this.FinishRequest(httpContext.WorkerRequest, httpContext, null);
  80. }
  81. }
  82. catch (Exception e)
  83. {
  84. httpContext.Response.InitResponseWriter();
  85. this.FinishRequest(wr, httpContext, e);
  86. }
  87. }

//进入EnsureFirstRequestInit

  1. // System.Web.HttpRuntime
  2. private void EnsureFirstRequestInit(HttpContext context)
  3. {
  4. if (this._beforeFirstRequest)
  5. {
  6. bool flag = false;
  7. try
  8. {
  9. Monitor.Enter(this, ref flag);
  10. if (this._beforeFirstRequest)
  11. {
  12.  
  13. //设置第一次请求为false
  14. this._firstRequestStartTime = DateTime.UtcNow;
  15. this.FirstRequestInit(context);
  16. this._beforeFirstRequest = false;
  17. context.FirstRequest = true;
  18. }
  19. }
  20. finally
  21. {
  22. if (flag)
  23. {
  24. Monitor.Exit(this);
  25. }
  26. }
  27. }
  28. }

Application中有26个方法,从上到下有19个请求管道事件

1.熟悉请求管道实现程序运行的全过程:

(1):BeginRequest: 开始处理请求。当ASP.NET运行时接收到新的HTTP请求的时候引发这个事件
(2):AuthenticateRequest授权验证请求,获取用户授权信息。当ASP.NET 运行时准备验证用户身份的时候引发这个事件
(3):PostAuthenticateRequest获取成功
(4): AunthorizeRequest 授权,一般来检查用户是否获得权限。当ASP.NET运行时准备授权用户访问资源的时候引发这个事件
(5):PostAuthorizeRequest:获得授权
(6):ResolveRequestCache:获取页面缓存结果
(7):PostResolveRequestCache 已获取缓存
(8):PostMapRequestHandler 创建页面对象
(9):AcquireRequestState 获取Session-----先判断当前页面对象是否实现了IRequiresSessionState接口,如果实现了,则从浏览器发来的请求报文体中获得SessionID,并到服务器的Session池中获得对应的Session对象,最后赋值给HttpContext的Session属性
(10)PostAcquireRequestState 获得Session
(11)PreRequestHandlerExecute:准备执行页面对象执行页面对象的ProcessRequest方法。在ASP.NET开始执行HTTP请求的处理程序之前引发这个事件。在这个事件之后,ASP.NET 把该请求转发给适当的HTTP处理程序。

(12)PostRequestHandlerExecute 执行完页面对象了。在HTTP处理程序结束执行的时候引发这个事件
(13)ReleaseRequestState 释放请求状态
(14)PostReleaseRequestState 已释放请求状态
(15)UpdateRequestCache 更新缓存
(16)PostUpdateRequestCache 已更新缓存
(17)LogRequest 日志记录
(18)PostLogRequest 已完成日志
(19)EndRequest 完成。把响应内容发送到客户端之前引发这个事件。

转载一篇比较详细的生命周期文章:http://www.cnblogs.com/Cwj-XFH/p/6752177.html

Asp.Net请求处理机制中IsApiRuntime解析的更多相关文章

  1. 从Nginx的Web请求处理机制中剖析多进程、多线程、异步IO

    Nginx服务器web请求处理机制 从设计架构来说,Nginx服务器是与众不同的.不同之处一方面体现在它的模块化设计,另一方面,也是最重要的一方面,体现在它对客户端请求的处理机制上. Web服务器和客 ...

  2. asp.net请求响应模型原理随记回顾

    asp.net请求响应模型原理随记回顾: 根据一崇敬的讲师总结:(会存在些错误,大家可以做参考) 1.-当在浏览器输入url后,客户端会将请求根据http协议封装成为http请求报文.并通过主sock ...

  3. Asp.Net请求响应过程

    Asp.Net请求响应过程 在之前,我们写了自己的Asp.Net框架,对整个流程有了一个大概的认识.这次我们来看一下Asp.Net整个请求处理过程是怎么样的. 浏览器封装请求报文,发送请求到达服务器, ...

  4. [译] ASP.NET 生命周期 – ASP.NET 请求生命周期(二)

    ASP.NET 请求生命周期 全局应用类也可以用来跟踪每个独立请求的生命周期,包括请求从 ASP.NET 平台传递到 MVC 框架.ASP.NET 框架会创建一个定义在 Global.asax 文件中 ...

  5. NET/ASP.NET Routing路由(深入解析路由系统架构原理)(转载)

    NET/ASP.NET Routing路由(深入解析路由系统架构原理) 阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模 ...

  6. ASP.Net请求小周期

    另一篇另篇2 ASP.NET请求处理全过程 一个ASP.NET请求过程中,从浏览器中发出一个Web请求 到 这个请求被响应并显示在浏览器中的过程中究竟会发生哪些不同的事件,当我们进入这个事件之旅时,我 ...

  7. ASP.NET请求过程-从源码角度研究MVC路由、Handler、控制器

    路由常用对象 RouteBase 用作表示 ASP.NET 路由的所有类的基类.        就是路由的一个基础抽象类. // // 摘要: // 用作表示 ASP.NET 路由的所有类的基类. [ ...

  8. ASP.NET请求过程-Handler

    什么事Handler asp.net程序所有的请求都是handler处理的.以前的webform我们访问的地址是xxxxx.aspx地址,其实他也会到一个handler(我们写的业务代码都在handl ...

  9. 【深入ASP.NET原理系列】--ASP.NET请求管道、应用程序生命周期、整体运行机制

    微软的程序设计和相应的IDE做的很棒,让人很快就能有生产力..NET上手容易,生产力很高,但对于一个不是那么勤奋的人,他很可能就不再进步了,没有想深入下去的动力,他不用去理解整个框架和环境是怎么执行的 ...

随机推荐

  1. 安卓图片框架:universal-image-loader的高速使用

    在安卓开发过程中难免会遇到下面几个情况: 1.图片异步载入 2.图片缓存 3.图片显示 4.其他--(忘记了) 以上的这些情况,可能要自己去写不少代码去实现这些功能.并且对于一些新手,可能写了半天,发 ...

  2. Linux Kernel系列一:开篇和Kernel启动概要

    前言 近期几个月将Linux Kernel的大概研究了一下,以下须要进行深入具体的分析.主要将以S3C2440的一块开发板为硬件实体.大概包含例如以下内容: 1 bootloader分析,以uboot ...

  3. 数据存储(三)--JSON数据处理

    JSON是一种轻量级的数据交换格式,具有良好的可读和便于高速编写的特性,从而能够在不同平台间进行数据交换.JSON採用兼容性非常高的文本格式,同一时候也具备类似于C语言体系的行为.JSON能够将Jav ...

  4. Mina入门:mina版之HelloWorld

    一,前言: 在完成上篇文章<Mina入门:Java NIO框架Mina.Netty.Grizzly简介与对比>之后,我们现在可以正式切入Mina入门学习了. 二,搭建项目结构与解决项目依赖 ...

  5. C#中的USB库 WinUSB

    NET C#中的USB库WinUSB,的libusb - Win32和的libusb - 1.0.使用公共设备类,应用程序与所有未经修改的操作系统和驱动程序.大量的示例代码. http://sourc ...

  6. @property和@synthesize

    main.m #import <Foundation/Foundation.h> #import "Student.h" int main(int argc, cons ...

  7. C#委托,事件,匿名委托

    作为一个初学者,写下来是当做自己的学习笔记,希望在以后遇到问题的时候能够快速的找到方法 如果能帮助跟我一样的新人是更好不过的了        如果有什么不正确或者可以改进的地方也希望大家能够指出来  ...

  8. light oj 1027 A Dangerous Maze

    一道数学期望题,唉唉,概率论学的不好啊~~ 求走出迷宫的期望时间. 由于有的门会回到起点,所以有可能会走很多遍,设能走出去的门的个数为n1,总的个数为n,那么一次走出去的概率为n1/n,走一次的用的平 ...

  9. BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )

    数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...

  10. Windows Server 2008防火墙问题及Sql Server2005用户登录问题

    一.Windows Server 2008防火墙问题 1.  问题: 1.在 Windows 安全中心中单击“立即打开”以打开 Windows 防火墙时,会收到以下错误消息:安全中心无法打开 Wind ...