在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
WebForms和WebServices作为.NET平台构建Web程序的两大利器,以其开发简单、易于部署的特点得到了广泛的应用,但殊不知微软公司在背后为我们做了大量的基础性工作,以至于我们开发人员只需简单地拖拖控件、写写一些页面级的代码就可以轻松地实现一些简单的应用程序。当然这种封装也不是没有好处的,至少从开发的角度而言它就可以极大地降低开发的难度,但是这种过度的封装使得我们开发人员当遇到有可能由底层引起的问题时就会束手无策,而且也会使得我们对知识的掌握和理解只停留在了表面而不得其内在本质。正是基于此,所以作者决定以一种探索的精神去试图解析和研究ASP.NET的内部运行机制,当然由于本人水平有限,也不可能对其各个方面理解很到位,姑且就当作本人的一家之言吧,有不对的地方还请各位同仁指正,这样大家可以共同学习提高。 一、IIS处理模型 从用户发出一个请求(一般而言就是在浏览器地址栏中键入一个URL),到这个请求到达服务器后,最先作出响应的就是IIS(本部分只关注ASP.NET部分,至于TCP/IP不在讨论范围),所以我们就先从这开始讲起。由于IIS有不同的版本,而且其处理模型也大相径庭,所以我会单独分别加以说明和解释。 IIS 5 处理模型 从上图我们可以清楚地知道,IIS在用户请求到达之后都做了哪些事情: 1.当用户请求到达后,工作在内核模式的TCP/IP驱动首先检测到请求,然后将其直接路由到inetinfo.exe进程; 3.用户请求由命名管道(为了提高性能,否则要在两个不同的进程间传递)从inetinfo.exe传给工作者进程aspnet_wp.exe; 4.aspnet_wp.exe将用户请求交由HTTP运行时即.NET Runtime处理(接下来的处理流程将会在后面讨论)。 IIS 6 处理模型 从上图来分析IIS 6架构的处理流程: 当应用程序池接收到HTTP请求后,交由在此应用程序池中运行的工作者进程Worker Process: w3wp.exe来处理此HTTP请求。 注意:工作者进程运行在非托管环境,而.NET中的对象则运行在托管环境之上(CLR),它们之间的桥梁就是ISAPI扩展。 二、.NET运行时 上面的图形简单描述了大概的处理流程,下面再用文字做些简单的说明: 1.当请求到达.NET Runtime后,接下来的处理操作就将在托管环境中完成。首先.NET Runtime做两个动作,一是准备Hosting Environment,二是由ApplicationManager创建一个AppDomain并且把处理权交由AppDomain继续完成; 2.在AppDomain中,由对象ISAPIRuntime启动操作,一方面经方法ProcessRequest()得到HttpWorkerRequest对象,另一方面由方法StartProcessing()生成HttpRuntime对象,接下来把处理权交给了HttpRuntime(HttpWorkerRequest对象将作为HttpRuntime方法中的参数被使用); 3.HttpRuntime中,方法ProcessRequest将处理请求: [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)] public static void ProcessRequest(HttpWorkerRequest wr) { if (wr == null) { throw new ArgumentNullException("wr"); } if (UseIntegratedPipeline)
{ throw new PlatformNotSupportedException(System.Web.SR.GetString("Method_Not_Supported_By_Iis_Integrated_Mode", new object[] { "HttpRuntime.ProcessRequest" })); } ProcessRequestNoDemand(wr); } internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) { RequestQueue queue = _theRuntime._requestQueue; if (queue != null) { wr = queue.GetRequestToExecute(wr); } if (wr != null) { CalculateWaitTimeAndUpdatePerfCounter(wr); wr.ResetStartTime(); ProcessRequestNow(wr); } } internal static void ProcessRequestNow(HttpWorkerRequest wr) { _theRuntime.ProcessRequestInternal(wr); } ProcessRequestInternal private void ProcessRequestInternal(HttpWorkerRequest wr) { HttpContext context; try
{ context = new HttpContext(wr, false); } catch
{ wr.SendStatus(400, "Bad Request");
wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>"); wr.SendResponseFromMemory(bytes, bytes.Length); wr.FlushResponse(true);
wr.EndOfRequest(); return;
} wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);
Interlocked.Increment(ref this._activeRequestCount); HostingEnvironment.IncrementBusyCount(); try
{ try
{ this.EnsureFirstRequestInit(context);
} catch
{ if (!context.Request.IsDebuggingRequest)
{ throw;
} } context.Response.InitResponseWriter(); IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); if (applicationInstance == null) { throw new HttpException(System.Web.SR.GetString("Unable_create_app_object")); } if (EtwTrace.IsTraceEnabled(5, 1))
{ EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start");
} if (applicationInstance is IHttpAsyncHandler) { IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance; context.AsyncAppHandler = handler2; handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context);
} else
{ applicationInstance.ProcessRequest(context); this.FinishRequest(context.WorkerRequest, context, null); } } catch (Exception exception)
{ context.Response.InitResponseWriter(); this.FinishRequest(wr, context, exception);
} } context = new HttpContext(wr, false); -- 基于HttpWorkerRequest生成HttpContext IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); -- 得到HttpApplication handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context); -- 由HttpApplication处理请求 4.下面我们来看看HttpApplicationFactory.GetApplicationInstance(context)到底做了什么? internal static IHttpHandler GetApplicationInstance(HttpContext context) { if (_customApplication != null) { return _customApplication;
} if (context.Request.IsDebuggingRequest)
{ return new HttpDebugHandler(); } _theApplicationFactory.EnsureInited(); _theApplicationFactory.EnsureAppStartCalled(context); return _theApplicationFactory.GetNormalApplicationInstance(context);
} private HttpApplication GetNormalApplicationInstance(HttpContext context)
{ HttpApplication application = null;
lock (this._freeList) { if (this._numFreeAppInstances > 0) { application = (HttpApplication) this._freeList.Pop();
this._numFreeAppInstances--;
if (this._numFreeAppInstances < this._minFreeAppInstances) { this._minFreeAppInstances = this._numFreeAppInstances; } } } if (application == null) { application = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType);
using (new ApplicationImpersonationContext()) { application.InitInternal(context, this._state, this._eventHandlerMethods); } } return application;
}
通过上面的方法我们最终获得了HttpApplication对象; 5.如果我们继续追踪代码application.InitInternal(context, this._state, this._eventHandlerMethods);看会获得什么? InitInternal internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) { this._state = state;
PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES); try
{ try
{ this._initContext = context;
this._initContext.ApplicationInstance = this; context.ConfigurationPath = context.Request.ApplicationPathObject; using (new HttpContextWrapper(context)) { if (HttpRuntime.UseIntegratedPipeline)
{ try
{ context.HideRequestResponse = true;
this._hideRequestResponse = true; this.InitIntegratedModules();
goto Label_006B;
} finally
{ context.HideRequestResponse = false;
this._hideRequestResponse = false; } } this.InitModules();
Label_006B: if (handlers != null) 全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论