ASP.NET Application生命周期概括(一)

读了Rick Strahl的经典文章“A low-level Look at the ASP.NET Architecture”

http://www.west-wind.com/presentations/howaspnetworks/howaspnetworks.asp

感到受益颇深。我从代码对ASP.NET Application生命周期做一下简单的概括。

1 根据扩展名映射路由到ASP.NET's processing pipeline

2 调用ISAPIRuntime类的ProcessRequest

public sealed class ISAPIRuntime : MarshalByRefObject, IISAPIRuntime, IRegisteredObject
{
// Fields
private static int _isThisAppDomainRemovedFromUnmanagedTable;
private const int WORKER_REQUEST_TYPE_IN_PROC = 0;
private const int WORKER_REQUEST_TYPE_IN_PROC_VERSION_2 = 2;
private const int WORKER_REQUEST_TYPE_OOP = 1;

// Methods
[SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
public ISAPIRuntime();
public void DoGCCollect();
public override object InitializeLifetimeService();
public int ProcessRequest(IntPtr ecb, int iWRType);
internal static void RemoveThisAppDomainFromUnmanagedTable();
public void StartProcessing();
public void StopProcessing();
void IRegisteredObject.Stop(bool immediate);
}

 3 调用HttpRuntime.ProcessRequestNoDemand(HttpWorkerRequest wr)

public int ProcessRequest(IntPtr ecb, int iWRType)
{
IntPtr zero = IntPtr.Zero;
if (iWRType == 2)
{
zero = ecb;
ecb = UnsafeNativeMethods.GetEcb(zero);
}
ISAPIWorkerRequest wr = null;
try
{
bool useOOP = iWRType == 1;
wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
wr.Initialize();
string appPathTranslated = wr.GetAppPathTranslated();
string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
{
HttpRuntime.ProcessRequestNoDemand(wr);
return 0;
}
HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated }));
return 1;
}
catch (Exception exception)
{
try
{
WebBaseEvent.RaiseRuntimeError(exception, this);
}
catch
{
}
if ((wr == null) || !(wr.Ecb == IntPtr.Zero))
{
throw;
}
if (zero != IntPtr.Zero)
{
UnsafeNativeMethods.SetDoneWithSessionCalled(zero);
}
if (exception is ThreadAbortException)
{
Thread.ResetAbort();
}
return 0;
}
}

 4

internal static void ProcessRequestNoDemand(HttpWorkerRequest wr)
{
RequestQueue queue = _theRuntime._requestQueue;
wr.UpdateInitialCounters();
if (queue != null)
{
wr = queue.GetRequestToExecute(wr);
}
if (wr != null)
{
CalculateWaitTimeAndUpdatePerfCounter(wr);
wr.ResetStartTime();
ProcessRequestNow(wr);
}
}

 5

internal static void ProcessRequestNow(HttpWorkerRequest wr)
{
_theRuntime.ProcessRequestInternal(wr);
}


6 经过调试发现这里运行的是BeginProcessRequest方法,我一开始一直误解为运行的是ProcessRequest方法.

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(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);
}
}

 查看HttpContext的构造函数,我们可以看到HttpRequest,HttpResponse的生成过程

internal HttpContext(HttpWorkerRequest wr, bool initResponseWriter)
{
this._timeoutStartTime = DateTime.MinValue;
this._wr = wr;
this.Init(new HttpRequest(wr, this), new HttpResponse(wr, this));
if (initResponseWriter)
{
this._response.InitResponseWriter();
}
PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_EXECUTING);
}

7

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;
}

8 此处的_stepManager是一个ApplicationStepManager对象

private void ResumeSteps(Exception error)
{
this._stepManager.ResumeSteps(error);
}

 9 然后运行HttpApplication的 ExecuteStep(IExecutionStep step, ref bool completedSynchronously)方法,
   代码中标记的_execSteps是IExecutionStep[]数组,在HttpApplication类中有很多继承IExecutionStep接口的类

  • AsyncEventExecutionStep
  • CallFilterExecutionStep
  • CallHandlerExecutionStep
  • MapHandlerExecutionStep
  • MaterializeHandlerExecutionStep
  • NoopExecutionStep
  • SendResponseExecutionStep
  • SyncEventExecutionStep
  • UrlMappingsExecutionStep
  • ValidatePathExecutionStep
  • ValidateRequestExecutionStep

 这些类都包含了相应的操作

我们可以看到_execSteps的初始化是在BuildSteps方法中发生的

 

internal class ApplicationStepManager : HttpApplication.StepManager
{
// Fields
private int _currentStepIndex;
private int _endRequestStepIndex;
private HttpApplication.IExecutionStep[] _execSteps;
private int _numStepCalls;
private int _numSyncStepCalls;
private WaitCallback _resumeStepsWaitCallback;

// Methods
internal ApplicationStepManager(HttpApplication app) : base(app)
{
}

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.ValidateRequestExecutionStep(app));
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;
}

internal override void InitRequest()
{
this._currentStepIndex = -1;
this._numStepCalls = 0;
this._numSyncStepCalls = 0;
base._requestCompleted = false;
}

[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_0045:
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_0045;
}
}
}
}
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();
}
}
}

 

 现在知道了HttpApplication是怎么去Raise那些事件的!都是通过ExecuteStep实现的。

BeginRequest,AuthenticateRequest等都是通过SyncEventExecutionStep这个类实现的。

 

internal class SyncEventExecutionStep : HttpApplication.IExecutionStep
{
// Fields
private HttpApplication _application;
private EventHandler _handler;

// Methods
internal SyncEventExecutionStep(HttpApplication app, EventHandler handler)
{
this._application = app;
this._handler = handler;
}

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);
}
}
}

// Properties
internal EventHandler Handler
{
get
{
return this._handler;
}
}

bool HttpApplication.IExecutionStep.CompletedSynchronously
{
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
get
{
return true;
}
}

bool HttpApplication.IExecutionStep.IsCancellable
{
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
get
{
return true;
}
}
}

 

 

转载于:https://www.cnblogs.com/edward44444/archive/2012/04/02/2430573.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值