深入理解ASP.NET的内部运行机制(转)

WebForms和WebServices作为.NET平台构建Web程序的两大利器,以其开发简单、易于部署的特点得到了广泛的应用,但殊不知微软公司在背后为我们做了大量的基础性工作,以至于我们开发人员只需简单地拖拖控件、写写一些页面级的代码就可以轻松地实现一些简单的应用程序。当然这种封装也不是没有好处的,至少从开发的角度而言它就可以极大地降低开发的难度,但是这种过度的封装使得我们开发人员当遇到有可能由底层引起的问题时就会束手无策,而且也会使得我们对知识的掌握和理解只停留在了表面而不得其内在本质。正是基于此,所以作者决定以一种探索的精神去试图解析和研究ASP.NET的内部运行机制,当然由于本人水平有限,也不可能对其各个方面理解很到位,姑且就当作本人的一家之言吧,有不对的地方还请各位同仁指正,这样大家可以共同学习提高。

一、IIS处理模型

  从用户发出一个请求(一般而言就是在浏览器地址栏中键入一个URL),到这个请求到达服务器后,最先作出响应的就是IIS(本部分只关注ASP.NET部分,至于TCP/IP不在讨论范围),所以我们就先从这开始讲起。由于IIS有不同的版本,而且其处理模型也大相径庭,所以我会单独分别加以说明和解释。

IIS 5 处理模型

从上图我们可以清楚地知道,IIS在用户请求到达之后都做了哪些事情:

1.当用户请求到达后,工作在内核模式的TCP/IP驱动首先检测到请求,然后将其直接路由到inetinfo.exe进程;

  • inetinfo.exe通过监听WinSock端口(常见的TCP 80端口)接收请求,然后对其进行处理或者交由其扩展组件(ISPAI Extensions)进行处理;

  • IIS中的Metabase维护着一份脚本映射扩展表,即ISAPI Extension Mapping数据表,是用Binary写的。该数据表的作用就是当请求到达IIS的时候,IIS会分析该请求的资源文件的后缀名,然后再通过ISAPI Extension Mapping找到对应的ISAPI Extension;
  • 找到对应的ISAPI Extension后就可以把此请求交由其处理了,例如.aspx文件将由aspnet_isapi.dll来处理;
  • 如果找不到,即一个文件的扩展名没有被映射到ASP.NET,那么ASP.NET就不会去接收这个请求,当然更不会去处理此请求;
  • 我们可以自定义一个Handler去处理一个特殊的文件名扩展,当然前提是你必须得Map到ASP.NET并且必须在你应用程序的Web.config文件中注册这个自定义的Handler,更多信息,请参看文章//TODO
  • 3.用户请求由命名管道(为了提高性能,否则要在两个不同的进程间传递)从inetinfo.exe传给工作者进程aspnet_wp.exe;

    4.aspnet_wp.exe将用户请求交由HTTP运行时即.NET Runtime处理(接下来的处理流程将会在后面讨论)。

    IIS 6 处理模型

    从上图来分析IIS 6架构的处理流程:

  • HTTP.SYS:运行于Windows核心(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求(通常来自网络中另一台计算机上的浏览器),根据请求的URL将其转发给相应的应用程序池 (Application Pool)。当此HTTP请求处理完成时,它又负责将处理结果发送出去(其接收者通常为发出HTTP请求的浏览器)。为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来。
  • Application Pool:  相对于IIS5,IIS6改变了这个处理模型,IIS不再直接寄宿像ISAPI扩展的任何外部可执行代码。代替的是,IIS总会保持一个单独的工作进程:应用程序池。所有的处理都发生在这个进程里,包括ISAPI dll的执行。对于IIS6而言,应用程序池是一个重大的改进,因为它们允许以更小的粒度控制一个指定进程的执行。你可以为每一个虚拟目录或者整个Web站点配置应用程序池,这可以使你很容易的把每一个应用程序隔离到各自的进程里,这样就可以把它与运行在同一台机器上其他程序完全隔离。从Web处理的角度看,如果一个进程死掉,至少它不会影响到其它的进程。
    当应用程序池接收到HTTP请求后,交由在此应用程序池中运行的工作者进程Worker Process: w3wp.exe来处理此HTTP请求。
  • Worker Process: 当工作者进程接收到请求后,首先根据后缀找到并加载对应的ISAPI扩展 (对于aspx而言就是aspnet_isapi.dll),工作者进程加载完aspnet_isapi.dll后,由aspnet_isapi.dll负责加载ASP.NET应用程序的运行环境即CLR (.NET Runtime)。
    注意:工作者进程运行在非托管环境,而.NET中的对象则运行在托管环境之上(CLR),它们之间的桥梁就是ISAPI扩展。
  • WAS(Web Admin Service:这是一个监控程序,它一方面可以存取放在InetInfo元数据库(Metabase)中的各种信息,另一方面也负责监控应用程序池(Application Pool)中的工作者进程的工作状态况,必要时它会关闭一个老的工作者进程并创建一个新的取而代之。
  • 二、.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);

        }

    }

    虽然上面给出了4个方法,但实际的处理是在第四个方法即最后一个中,请注意方法中的
    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)

                    {

                        this.HookupEventHandlersForApplicationAndModules(handlers);

                    }

                    this._context = context;

                    if (HttpRuntime.UseIntegratedPipeline && (this._context != null))

                    {

                        this._context.HideRequestResponse = true;

                    }

                    this._hideRequestResponse = true;

                    try

                    {

                        this.Init();

                    }

                    catch (Exception exception)

                    {

                        this.RecordError(exception);

                    }

                }

                if (HttpRuntime.UseIntegratedPipeline && (this._context != null))

                {

                    this._context.HideRequestResponse = false;

                }

                this._hideRequestResponse = false;

                this._context = null;

                this._resumeStepsWaitCallback = new WaitCallback(this.ResumeStepsWaitCallback);

                if (HttpRuntime.UseIntegratedPipeline)

                {

                    this._stepManager = new PipelineStepManager(this);

                }

                else

                {

                    this._stepManager = new ApplicationStepManager(this);

                }

                this._stepManager.BuildSteps(this._resumeStepsWaitCallback);

            }

            finally

            {

                this._initInternalCompleted = true;

                context.ConfigurationPath = null;

                this._initContext.ApplicationInstance = null;

                this._initContext = null;

            }

        }

        catch

        {

            throw;

        }

    }

    请注意方法的这些地方
    this.InitModules();初始化所有的Modules,包含用户自定义的HttpModules

    private void InitModules()
    {

        this._moduleCollection = RuntimeConfig.GetAppConfig().HttpModules.CreateModules();

        this.InitModulesCommon();

    }

    private void InitModulesCommon()

    {

        int count = this._moduleCollection.Count;

        for (int i = 0; i < count; i++)

        {

            this._currentModuleCollectionKey = this._moduleCollection.GetKey(i);

            this._moduleCollection[i].Init(this);

        }

        this._currentModuleCollectionKey = null;

        this.InitAppLevelCulture();

    }

    this._stepManager.BuildSteps(this._resumeStepsWaitCallback);

    internal override void BuildSteps(WaitCallback stepCallback)
    {

        ArrayList steps = new ArrayList();

        HttpApplication app = base._application;

        bool flag = false;

        UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;

        flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0);

        steps.Add(new HttpApplication.ValidatePathExecutionStep(app));

        if (flag)

        {

            steps.Add(new HttpApplication.UrlMappingsExecutionStep(app));

        }

        app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);

        steps.Add(new HttpApplication.MapHandlerExecutionStep(app));

        app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);

        steps.Add(new HttpApplication.CallHandlerExecutionStep(app));

        app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);

        steps.Add(new HttpApplication.CallFilterExecutionStep(app));

        app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);

        app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps);

        this._endRequestStepIndex = steps.Count;

        app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);

        steps.Add(new HttpApplication.NoopExecutionStep());

        this._execSteps = new HttpApplication.IExecutionStep[steps.Count];

        steps.CopyTo(this._execSteps);

        this._resumeStepsWaitCallback = stepCallback;

    }

    你看到什么?对,这就是我们常说的管道事件序列(具体的Pipelines也会在下一部分介绍)

    我们继续深入代码来看看CreateEventExecutionSteps()和CallHandlerExecutionStep()

    private void CreateEventExecutionSteps(object eventIndex, ArrayList steps)
    {

        AsyncAppEventHandler handler = this.AsyncEvents[eventIndex];

        if (handler != null)

        {

            handler.CreateExecutionSteps(this, steps);

        }

        EventHandler handler2 = (EventHandler) this.Events[eventIndex];

        if (handler2 != null)

        {

            Delegate[] invocationList = handler2.GetInvocationList();

            for (int i = 0; i < invocationList.Length; i++)

            {

                steps.Add(new SyncEventExecutionStep(this, (EventHandler) invocationList[i]));

            }

        }

    }

    internal CallHandlerExecutionStep(HttpApplication app)

    {

        this._application = app;

        this._completionCallback = new AsyncCallback(this.OnAsyncHandlerCompletion);

    }

    6.接下来就是开始HttpApplication的BeginProcessRequest()方法了
    handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context)

    IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {

        this._context = context;

        this._context.ApplicationInstance = this;

        this._stepManager.InitRequest();

        this._context.Root();

        HttpAsyncResult result = new HttpAsyncResult(cb, extraData);

        this.AsyncResult = result;

        if (this._context.TraceIsEnabled)

        {

            HttpRuntime.Profile.StartRequest(this._context);

        }

        this.ResumeSteps(null);

        return result;

    }

    ResumeSteps

     

    [DebuggerStepperBoundary]

    internal override void ResumeSteps(Exception error)

    {

        bool flag = false;

        bool completedSynchronously = true;

        HttpApplication application = base._application;

        HttpContext context = application.Context;

        HttpApplication.ThreadContext context2 = null;

        AspNetSynchronizationContext syncContext = context.SyncContext;

        lock (base._application)

        {

            try

            {

                context2 = application.OnThreadEnter();

            }

            catch (Exception exception)

            {

                if (error == null)

                {

                    error = exception;

                }

            }

            try

            {

                try

                {

                Label_0040:

                    if (syncContext.Error != null)

                    {

                        error = syncContext.Error;

                        syncContext.ClearError();

                    }

                    if (error != null)

                    {

                        application.RecordError(error);

                        error = null;

                    }

                    if (syncContext.PendingOperationsCount > 0)

                    {

                        syncContext.SetLastCompletionWorkItem(this._resumeStepsWaitCallback);

                    }

                    else

                    {

                        if ((this._currentStepIndex < this._endRequestStepIndex) && ((context.Error != null) || base._requestCompleted))

                        {

                            context.Response.FilterOutput();

                            this._currentStepIndex = this._endRequestStepIndex;

                        }

                        else

                        {

                            this._currentStepIndex++;

                        }

                        if (this._currentStepIndex >= this._execSteps.Length)

                        {

                            flag = true;

                        }

                        else

                        {

                            this._numStepCalls++;

                            context.SyncContext.Enable();

                            error = application.ExecuteStep(this._execSteps[this._currentStepIndex], ref completedSynchronously);

                            if (completedSynchronously)

                            {

                                this._numSyncStepCalls++;

                                goto Label_0040;

                            }

                        }

                    }

                }

                finally

                {

                    if (context2 != null)

                    {

                        try

                        {

                            context2.Leave();

                        }

                        catch

                        {

                        }

                    }

                }

            }

            catch

            {

                throw;

            }

        }

        if (flag)

        {

            context.Unroot();

            application.AsyncResult.Complete(this._numStepCalls == this._numSyncStepCalls, null, null);

            application.ReleaseAppInstance();

        }

    }

    ExecuteStep

     

    internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously)

    {

        Exception exception = null;

        try

        {

            try

            {

                if (step.IsCancellable)

                {

                    this._context.BeginCancellablePeriod();

                    try

                    {

                        step.Execute();

                    }

                    finally

                    {

                        this._context.EndCancellablePeriod();

                    }

                    this._context.WaitForExceptionIfCancelled();

                }

                else

                {

                    step.Execute();

                }

                if (!step.CompletedSynchronously)

                {

                    completedSynchronously = false;

                    return null;

                }

            }

            catch (Exception exception2)

            {

                exception = exception2;

                if (ImpersonationContext.CurrentThreadTokenExists)

                {

                    exception2.Data["ASPIMPERSONATING"] = string.Empty;

                }

                if ((exception2 is ThreadAbortException) && ((Thread.CurrentThread.ThreadState & System.Threading.ThreadState.AbortRequested) == System.Threading.ThreadState.Running))

                {

                    exception = null;

                    this._stepManager.CompleteRequest();

                }

            }

            catch

            {

            }

        }

        catch (ThreadAbortException exception3)

        {

            if ((exception3.ExceptionState != null) && (exception3.ExceptionState is CancelModuleException))

            {

                CancelModuleException exceptionState = (CancelModuleException) exception3.ExceptionState;

                if (exceptionState.Timeout)

                {

                    exception = new HttpException(System.Web.SR.GetString("Request_timed_out"), null, 0xbb9);

                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT);

                }

                else

                {

                    exception = null;

                    this._stepManager.CompleteRequest();

                }

                Thread.ResetAbort();

            }

        }

        completedSynchronously = true;

        return exception;

    }

    void HttpApplication.IExecutionStep.Execute()

    {

        string str = null;

        if (this._handler != null)

        {

            if (EtwTrace.IsTraceEnabled(5, 2))

            {

                str = this._handler.Method.ReflectedType.ToString();

                EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_ENTER, this._application.Context.WorkerRequest, str);

            }

            this._handler(this._application, this._application.AppEvent);

            if (EtwTrace.IsTraceEnabled(5, 2))

            {

                EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, this._application.Context.WorkerRequest, str);

            }

        }

    }

    HttpApplication.IExecutionStep.Execute

     

    void HttpApplication.IExecutionStep.Execute()

    {

        HttpContext context = this._application.Context;

        IHttpHandler handler = context.Handler;

        if (EtwTrace.IsTraceEnabled(4, 4))

        {

            EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_ENTER, context.WorkerRequest);

        }

        if ((handler != null) && HttpRuntime.UseIntegratedPipeline)

        {

            IIS7WorkerRequest workerRequest = context.WorkerRequest as IIS7WorkerRequest;

            if ((workerRequest != null) && workerRequest.IsHandlerExecutionDenied())

            {

                this._sync = true;

                HttpException exception = new HttpException(0x193, System.Web.SR.GetString("Handler_access_denied"));

                exception.SetFormatter(new PageForbiddenErrorFormatter(context.Request.Path, System.Web.SR.GetString("Handler_access_denied")));

                throw exception;

            }

        }

        if (handler == null)

        {

            this._sync = true;

        }

        else if (handler is IHttpAsyncHandler)

        {

            IHttpAsyncHandler handler2 = (IHttpAsyncHandler) handler;

            this._sync = false;

            this._handler = handler2;

            IAsyncResult result = handler2.BeginProcessRequest(context, this._completionCallback, null);

            if (result.CompletedSynchronously)

            {

                this._sync = true;

                this._handler = null;

                try

                {

                    handler2.EndProcessRequest(result);

                }

                finally

                {

                    context.Response.GenerateResponseHeadersForHandler();

                }

                if (EtwTrace.IsTraceEnabled(4, 4))

                {

                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);

                }

            }

        }

        else

        {

            this._sync = true;

            context.SyncContext.SetSyncCaller();

            try

            {

                handler.ProcessRequest(context);

            }

            finally

            {

                context.SyncContext.ResetSyncCaller();

                if (EtwTrace.IsTraceEnabled(4, 4))

                {

                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);

                }

                context.Response.GenerateResponseHeadersForHandler();

            }

        }

    }

    具体的含义就不去解释了,代码中全有,如果自己想追踪每一步,可用Reflector做反编译调试。

    三、管道事件序列Pipelines

      MSDN上的链接http://msdn.microsoft.com/en-us/library/system.web.httpapplication(v=vs.80).aspx

    时间: 2024-08-01 18:47:44

    深入理解ASP.NET的内部运行机制(转)的相关文章

    再理解Windows程序内部运行机制

    参照孙鑫<VC++深入详解> 创建Win32程序的步骤: 1. 编写WinMain函数 2. 设计窗口类(WNDCLASS) 3. 注册窗口类 4. 创建窗口 5. 显示并更新窗口(ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);) 6. 消息循环(不断地从消息队列中取出消息,并进行响应) 7. 窗口过程函数(处理发送给窗口的消息) 测试代码如下(在VS2010编译通过): #include <stdafx.h> #include

    IIS 内部运行机制

    ASP.NET是一个非常强大的构建Web应用的平台,它提供了极大的灵活性和能力以致于可以用它来构建所有类型的Web应用. 绝大多数的人只熟悉高层的框架如: WebForms 和 WebServices --这些都在ASP.NET层次结构在最高层. 这篇文章的资料收集整理自各种微软公开的文档,通过比较 IIS5.IIS6.IIS7 这三代 IIS 对请求的处理过程, 让我们熟悉 ASP.NET的底层机制并对请求(request)是怎么从Web服务器传送到ASP.NET运行时有所了解.通过对底层机制

    Windows程序内部运行机制 转自http://www.cnblogs.com/zhili/p/WinMain.html

    一.引言 要想熟练掌握Windows应用程序的开发,首先需要理解Windows平台下程序运行的内部机制,然而在.NET平台下,创建一个Windows桌面程序,只需要简单地选择Windows窗体应用程序就可以了,微软帮我们做了非常好的封装,以至于对于很多.NET开发人员至今也不清楚Windows 平台下程序运行的内部机制,所以本专题将深入剖析下Windows 程序的内部运行机制. 二.Windows平台下几个基础概念 有朋友会问,理解了程序运行的内部机制有什么用,因为在我们实际开发中用得微软提供的

    ASP.NET MVC的运行机制--url的全局分析

    全局 首先我们来看一副图片 首先,用户通过Web浏览器向服务器发送一条url请求,这里请求的url不再是xxx.aspx格式,而是http://HostName/ControllerName/ActionName/Parameters的样子.这个请求被ASP.NET MVC的路由映射系统截获.(路由映射可以在Global.asax中配置,我们一会再说)路由映射系统按照映射规则,解析出控制器名ControllerName,Action名ActionName和各个参数Parameters,然后,找寻

    MFC第一节-windows程序内部运行机制

    一.窗口 设计窗口类时: 1 typedef struct _WNDCLASS{ 2 UINT style; //如水平.垂直变化是否重绘,禁用Close,检测双击 3 WNDPROC lpfnWndProc;//窗口过程函数句柄 4 int cbClsExtra;//类附加内存 5 int cbWndExtra;//窗口附加内存 6 HANDLE hInstance;//实例句柄 7 HANDLE hIcon;//图标 8 HCURSOR hCursor;//光标 9 HBRUSH hbrBa

    Windows程序内部运行机制

    Windows程序内部运行机制 一.        API与SDK Windows操作系统提供了各种各样的函数,以方便我们开发Windows应用程序,这些函数是Windows操作系统提供给应用程序编程的接口(Application Programming Interface),简称为API函数.我们在编写Windows程序时所说的API函数,就是指系统提供的函数,所有主要的Windows函数都在Windows.h头文件中进行了说明. SDK的全称是Software Development Kit

    【vc】1_Windows程序内部运行机制

    创建一个Win32应用程序步骤: 1.编写WinMain函数; 2.创建窗口(步骤如下): a.设计(一个)窗口类(WNDCLASS) b.注册(该)窗口类. c.创建窗口. d.显示并更新窗口. 3.编写消息循环. 4.编写窗口过程函数. 1 //WinMain.cpp 2 #include <windows.h> 3 #include <stdio.h> 4 5 LRESULT CALLBACK WinAzeProc( 6 HWND hwnd, // handle to win

    第一章 Windows程序内部运行机制(4)WinMain函数

    WinMain函数相当于main函数,作为Windows程序的入口函数.当WinMain结束或返回时,Windows程序结束. 一个win32应用程序,该程序创建一个窗口并在窗口中响应键盘与鼠标消息,程序的实现步骤为: 1.WinMain函数的定义:2.创建一个窗口:3.进行消息循环:4.编写窗口过程 WinMain函数的定义: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, in

    WWindows程序内部运行机制

    Windows程序内部运行机制 ü      关键概念 1.句柄 句柄是整个Windows编程的基础.一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等. 2.消息与消息队列 windows程序设计是种事件驱动方式的程序设计,主要基于消息的.例如,当用户在窗口中华图时,按下鼠标左键,此时os会感知到这一事件,于是将此事件包装成一个消息,投递到应用程序的消息队