In order to better optimize the performance of the blog garden program, I recently optimized the code and studied the source code of asp.net in more depth. The source code of asp.net is completely identified by the Reflector tool. Although it is not the original code, it is enough. The principles and ideas of the source code are clearly presented to us. This is lucky for. NET developers!
When we develop an asp.net application, System. Web. UI. Page is the most common class. But how many people have carefully studied the source code of this class? From the related search, we can see that there are not many results. For example, you can use Google to search for "OnPageStartSessionObjects" in the ProcessRequestMain method. There are only four results.
Today, I spent half a day studying the most critical method for processing requests on the Page: ProcessRequestMain (). Here I will write my own understanding and share it with you, thank you for your criticism and correction. All in the code comment:
Note: For ease of reading and understanding, the Trace information output in the source code has been removed.
Public class Page
{
Private void ProcessRequestMain ()
{
Try
{
If (this. IsInAspCompatMode)
{
AspCompatApplicationStep. OnPageStartSessionObjects ();
}
// Pass the object in the current Context Session to the OnStartPage of asp
// Use <% @ ASPCOMPAT = "true" %> to set
// Reference: http://samples.gotdotnet.com/quickstart/aspplus/doc/cominterop.aspx
This. _ requestValueCollection = this. DeterminePostBackMode ();
// Check PostBackMode. If PostBack is enabled, obtain VIEWSTATE data and assign it to _ requestValueCollection.
Base. InitRecursive (null );
// Call the InitRecursive method of the base class to initialize the child control by recursion, for example, generating the Control ID and setting the Page attribute of the control.
// The OnInit () method will be called at this time
If (this. IsPostBack)
{
This. LoadPageViewState ();
// Load the view State data from _ requestValueCollection through deserialization. If the Layout of the page changes, the Child control re-recursively loads the view State (LoadViewStateRecursive ).
// After loading, obtain all the controls whose PostBack is to be processed from the view status data and register them with _ controlsRequiringPostBack.
This. ProcessPostData (this. _ requestValueCollection, true );
// Process the PostBack data, obtain all the control IDs from the PostBack data, and check each control. If the control (FindControl) cannot be found on the current page, save it to _ leftoverPostData.
// If the control exists, check again. If the control does not implement IPostBackDataHandler, but implements IPostBackEventHandler, register the control for event processing.
// If the control implements System. Web. UI. IPostBackDataHandler, The LoadPostData () method of the control is called at this time and added to _ changedPostDataConsumers,
// And remove the control from. _ controlsRequiringPostBack (assigned a value when LoadPageViewState is used.
// This removes all controls that implement the IPostBackDataHandler interface from _ controlsRequiringPostBack.
// Continue to process the remaining controls in _ controlsRequiringPostBack, But it is strange that the remaining controls are checked and IPostBackDataHandler is implemented,
// Call the LoadPostData () of the control (a bit more often, probably because the code generated by the Relector is incorrect) and put the _ changedPostDataConsumers. If not, put a new ArrayList variable,
// After the check, assign it to _ controlsRequiringPostBack. What is left in _ controlsRequiringPostBack? IPostBackDataHandler is not implemented,
// Controls that implement IPostBackEventHandler and controls that are not loaded, that is, controls that exist in the PostBack data but are not found in FindControl.
// Why are there unfound controls? We need to note that the OnLoad () event has not been executed yet,
// Some controls have not been loaded. The base. LoadRecursive () below triggers the OnLoad () event.
}
Base. LoadRecursive ();
// Trigger the OnLoad () event on the page-> recursively trigger the OnLoad () event of the Child control-> set the _ controlState status of the page to ControlState. Loaded
If (this. IsPostBack)
{
This. ProcessPostData (this. _ leftoverPostData, false );
// After understanding ProcessPostData (this. _ requestValueCollection, true), this is a good understanding. It is to check whether the control in _ controlsRequiringPostBack exists and implements
// IPostBackDataHandler. If implemented, call the LoadPostData () method of the control and add it to _ changedPostDataConsumers. ProcessPostData (this. _ leftoverPostData, false)
// This method serves the control loaded after OnLoad.
}
This. RaiseChangedEvents ();
// The control that does not implement the IPostBackDataHandler interface in _ changedPostDataConsumers (added data to the two ProcessPostData methods) triggers RaisePostDataChangedEvent.
This. RaisePostBackEvent (this. _ requestValueCollection );
// Trigger the RaisePostBackEvent event of the control that implements the IPostBackEventHandler interface in _ registeredControlThatRequireRaiseEvent and PostBack data.
Base. PreRenderRecursiveInternal ();
// Call EnsureChildControls to check whether the child control is created. If not, call CreateChildControls to create it.
// Trigger the OnPreRende event.
// Call the PreRenderRecursiveInternal method of the child control recursively
// Set. _ controlState to ControlState. PreRendered
This. SavePageViewState ();
// Save the view status data to. _ viewStateToPersist
Base. RenderControl (this. CreateHtmlTextWriter (this. Response. Output ));
// Output the current and all sub-Controls
}
Catch (ThreadAbortException)
{
Base. UnloadRecursive (true );
Return;
}
Catch (ConfigurationException)
{
Throw;
}
Catch (Exception exception1)
{
PerfCounters. IncrementCounter (AppPerfCounter. ERRORS_DURING_REQUEST );
PerfCounters. IncrementCounter (AppPerfCounter. ERRORS_TOTAL );
If (! This. HandleError (exception1 ))
{
Throw;
}
Return;
}
}
}