`
hududanyzd
  • 浏览: 775242 次
文章分类
社区版块
存档分类
最新评论

ASP.NET底层架构探索之处理请求

 
阅读更多

当一个请求到来时,它被路由到ISAPIRuntime.ProcessRequest()方法.这个方法调用HttpRuntime.ProcessRequest方法,它作一些重要的事情(用Reflector查看System.Web.HttpRuntime.ProcessRequestInternal方法):

  ·为请求创建一个新的HttpContext实例

  ·获取一个HttpApplication实例

  ·调用HttpApplication.Init()方法来设置管道的事件

  ·Init()方法触发开始ASP.NET管道处理的HttpApplication.ResumeProcessing()方法。

  首先一个新的HttpContext对象被创建并用来传递ISAPIWorkerRequest(ISAPI ECB的包装器).这个上下文在整个请求的生命周期总都是可用的并总可以通过静态属性HttpContext.Currect来访问.正像名字所暗示的那样,HttpContext对象代表了当前活动请求的上下文因为他包含了在请求生命周期中所有典型的你需要访问的重要对象:Request,Response,Application,Server,Cache.在请求处理的任何时候HttpContext.Current给你访问所有这些的能力.

  HttpContext对象也包含一个非常有用的Items集合,你可以用它来保存针对特定请求的数据.上下文对象在请求周期的开始时被创建,在请求结束时被释放,所有在Items集合中保存的数据只在这个特定的请求中可用.一个很好的使用的例子是请求日志机制,当你通过想通过在Global.asax中挂接Application_BeginRequest和Application_EndRequest方法记录请求的开始和结束时间(象在列表3中显示的那样).HttpContext对你就非常有用了-如果你在请求或页面处理的不同部分需要数据,你自由的使用它.

  列表3-使用HttpContext.Items集合使你在不同的管道事件中保存数据

protected void Application_BeginRequest(Object sender, EventArgs e)
{
 //*** Request Logging
 if (App.Configuration.LogWebRequests)
  Context.Items.Add("WebLog_StartTime",DateTime.Now);
}

protected void Application_EndRequest(Object sender, EventArgs e)
{
 // *** Request Logging
 if (App.Configuration.LogWebRequests)
 {
  try
  {
   TimeSpan Span = DateTime.Now.Subtract( (DateTime) Context.Items["WebLog_StartTime"] );
   int MiliSecs = Span.TotalMilliseconds;
   // do your logging
   WebRequestLog.Log(App.Configuration.ConnectionString,true,MilliSecs);
  }
 }
}

  一旦上下文被设置好,ASP.NET需要通过HttpApplication对象将收到的请求路由到适合的应用程序/虚拟目录.每个ASP.NET应用程序必须被设置到一个虚拟目录(或者Web根目录)而且每个”应用程序”是被单独的处理的。

  HttpApplication类似仪式的主人-它是处理动作开始的地方。

  域的主人:HttpApplication

  每个请求都被路由到一个HttpApplication对象上.HttpApplicationFactory类根据应用程序的负载为你的ASP.NET应用创建一个HttpApplication对象池并为每个请求分发HttpApplication对象的引用.对象池的大小受machine.config文件中ProcessModel键中的MaxWorkerThreads设置限制,默认是20个(译注:此处可能有误,根据Reflector反编译的代码,池的大小应该是100个,如果池大小小于100,HttpApplicationFactory会创建满100个,但是考虑到会有多个线程同时创建HttpApplication的情况,实际情况下有可能会超过100个)。

  对象池以一个更小的数字开始;通常是一个然后增长到和同时发生的需要被处理的请求数量一样.对象池被监视,这样在大负载下它可能会增加到最大的实例数量,当负载降低时会变回一个更小的数字。

  HttpApplication是你的Web程序的外部包装器,而且它被映射到在Global.asax里面定义的类上.它是进入HttpRuntime的第一个入口点.如果你查看Global.asax(或者对应的代码类)你会发现这

个类直接继承自HttpApplication:

public class Global : System.Web.HttpApplication

  HttpApplication的主要职责是作为Http管道的事件控制器,所以它的接口主要包含的是事件.事件挂接是非常广泛的,包括以下这些:

  ·BeginRequest

  ·AuthenticateRequest

  ·AuthorizeRequest

  ·ResolveRequestCache

  ·AquireRequestState

  ·PreRequestHandlerExecute

  ·…Handler Execution…

  ·PostRequestHandlerExecute

  ·ReleaseRequestState

  ·UpdateRequestCache

  ·EndRequest

  每个事件在Global.assx文件中以Application_前缀开头的空事件作为实现.例如, Application_BeginRequest(), Application_AuthorizeRequest()..这些处理器为了便于使用而提供因为它们是在程序中经常被使用的,这样你就不用显式的创建这些事件处理委托了。

  理解每个ASP.NET虚拟目录在它自己的应用程序域中运行,而且在应用程序域中有多个从ASP.NET管理的池中返回的HttpApplication实例同时运行,是非常重要的,这是多个请求可以被同时处理而不互相妨碍的原因。

  查看列表4来获得应用程序域,线程和HttpApplication之间的关系。

  列表4-显示应用程序域,线程和HttpApplication实例之间的关系。

private void Page_Load(object sender, System.EventArgs e)
{
 // Put user code to initialize the page here
 this.ApplicationId = ((HowAspNetWorks.Global) HttpContext.Current.ApplicationInstance).ApplicationId ;
 this.ThreadId = AppDomain.GetCurrentThreadId();

 this.DomainId = AppDomain.CurrentDomain.FriendlyName;

 this.ThreadInfo = "ThreadPool Thread: " + System.Threading.Thread.CurrentThread.IsThreadPoolThread.ToString() +"<br>Thread Apartment: " +
System.Threading.Thread.CurrentThread.ApartmentState.ToString();


 // *** Simulate a slow request so we can see multiple
 // requests side by side.
 System.Threading.Thread.Sleep(3000);
}

  这是随sample提供的demo的一部分,运行的结果在图5中显示.运行两个浏览器,打开这个演示页面可以看到不同的ID。

点击放大此图片

  图5-你可以通过同时运行多个浏览器来简单的查看应用程序域,应用程序池实例和请求线程是如何交互的。当多个请求同时发起,你可以看到线程ID和应用程序ID变化了,但是应用程序域还是同一个。

  你可能注意到在大多数请求上,当线程和HttpApplication ID变化时应用程序域ID却保持不变,虽然它们也可能重复(指线程和HttpApplication ID).HttpApplication是从一个集合中取出,

在随后到来的请求中可以被复用的,所以它的ID有时是会重复的.注意Application实例并不和特定的线程绑定-确切的说它们是被指定给当前请求的活动线程。


分享到:
评论

相关推荐

    了解ASP.NET底层架构

    ASP.NET底层架构 这篇文章以非常底层的视角讲述了Web请求(request)在ASP.NET框架中是如何流转的,从Web服务器,通过ISAPI直到请求处理器(handler)和你的代码.看看在幕后都发生了些什么,不要再把ASP.NET看成一个黑盒...

    [翻译]了解ASP.NET底层架构

    ASP.NET是一个非常强大的构建Web应用的平台,它提供了极大的灵活性和能力以致...在这篇文章中我将会讨论ASP.NET的底层机制并解释请求(request)是怎么从Web服务器传送到ASP.NET运行时然后如何通过ASP.NET管道来处理请求.

    ASP.NET底层架构

    这篇文章以非常底层的视角讲述了Web请求(request)在ASP.NET框架中是如何流转的,从Web服务器,通过ISAPI直到请求处理器(handler)和你的代码.看看在幕后都发生了些什么,不要再把ASP.NET看成一个黑盒了.

    ASP.NET架构详解

    ASP.NET底层机制,深入介绍ASP.NET处理请求的整个过程,详解HttpHandler,HttpModel,ISAPI等内容,好书,推荐推荐

    微软ASP.NET技术“乱谈”

    2014新年了,顺手写的一点文字,主要谈谈我对当前微软ASP.NET技术的看法,...  时至,ASP.NET底层的基础架构基本没太大变化,诸如使用HTTP处理管线处理HTTP请求,使用HTTP Module对原始HTTP请求进行“加工“,使用HT

    net学习笔记及其他代码应用

    要请求垃圾收集,可以调用下面的方法之一: System.gc() Runtime.getRuntime().gc() 37.String s = new String(\"xyz\");创建了几个String Object? 答:两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。...

    NodeJS体系架构-单线程事件循环

    我们将要讨论,NodeJS的底层工作原理是什么,它遵循怎样的处理模型,以及它是如何使用单线程模型处理来自客户端的并发请求。之前提到,NodeJS应用使用“单线程事件循环模型”(SingleThreadedEventLoopModel)处理...

    ExtAspNet v2.2.1 (2009-4-1) 值得一看

    -使得Asp.net的控件ImageButton具有和Asp.net的Button控件类似的行为(Ajax提交)(feedback:261629698)。 +TabStrip增加GetAddTabReference和GetRemoveTabReference两个函数,用来向TabStrip控件动态增加删除Tab。...

    ExtAspNet_v2.3.2_dll

    ExtAspNet - ExtJS based ASP.NET Controls with Full AJAX Support ExtAspNet是一组专业的Asp.net控件库,拥有原生的AJAX支持和丰富的UI效果, 目标是创建没有ViewState,没有JavaScript,没有CSS,没有...

    C#微软培训资料

    8.4 异常处理语句 .95 8.5 小 结 .100 第三部分 面向对象的 C#.101 第九章 面向对象的程序设计 .101 9.1 面向对象的基本概念.101 9.2 对象的模型技术 .103 9.3 面向对象的分析 .105 9.4 面向对象的设计...

    JDiy开发框架与javaWeb建站平台v1.0

    构造一个JDiyContext上下文对象,您可轻松的将JDiy应用于javaSE开发环境,使用JDiy框架方便的对底层数据库进行读写操作(数据的增删改查,附加XML字段、文件字段、事务处理等等)。  通过JDiyLoadFilter过滤器配置...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    为了增加系统的吞吐量,提高并发处理客户请求数量,系统采用了IBM服务器作为主机。在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。...

    JAVA上百实例源码以及开源项目源代码

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    JAVA上百实例源码以及开源项目

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

Global site tag (gtag.js) - Google Analytics