Dev Basics: ASP.NET Page Life Cycle, Part 4 [Event Wireup]

Apr 26, 2011 • Jay Harris

The first three parts of this series discuss the events that make up the ASP.NET Page Life Cycle, the order that these events execute on the page and on the controls, and that necessary evil called Data Binding, through which you add dynamic content to your new ASP.NET page. Raising those events happens automatically, without any developer oversight, but tapping in to those events—making them work for you—requires wiring special methods called Event Handlers to those events. This wiring can happen automatically by the system if you follow a few simple steps, or it can happen manually, with developers connecting each appropriate event to its handler. Both sides have their advantages as well as their drawbacks, but learning the nuances of event wiring can only strengthen your ASP.NET repertoire.

About the Series

When a request occurs for an ASP.NET page, the response is processed through a series of events before being sent to the client browser. These events, known as the ASP.NET Page Life Cycle, are a complicated headache when used improperly, manifesting as odd exceptions, incorrect data, performance issues, and general confusion. It seems simple when reading yet-another-book-on-ASP.NET, but never when applied in the real world. What is covered in a few short pages in many ASP.NET books (and sometimes even just a few short paragraphs), is much more complicated outside of a "Hello, World!" application and inside of the complex demands of the enterprise applications that developers create and maintain in their day-to-day work life. As close to the core as the life cycle is to any ASP.NET web application, the complications and catches behind this system never seems to get wide coverage on study guides or other documentation. But, they should.

Posts in this Series

Automatic Event Wireup

Page events can be automatically wired to their event handlers. That is, the code to assign the event handler to your event can be made optional, with the system automatically making the connection for the page, and thus, saving the developer a little bit of work. Automatic event wiring is enabled through a boolean property called AutoEventWireup on the ASP.NET Page Directive.

1

<%@ Page AutoEventWireup="true" %>

With this attribute set in the page directive, ASP.NET will automatically search for and wire up any event handlers that match the specific naming convention of Page_EventName, such as Page_Init or Page_Load. These methods can exist with or without the sender and EventArgs method arguments, though do note they must both be absent or both be present from the method signature; you cannot have one without the other.

1
2
3
4
5
6
7
8
9

protectedvoidPage_Init(){//Do some stuff}protectedvoidPage_Load(objectsender,EventArgse){//Do some stuff}

Drawbacks to Event Auro-Wire

There is no fancy compiler magic to wire these event handlers to the event; under AutoEventWireup, ASP.NET wires each event at run time when executing the page. This means that for every event in the ASP.NET Page Life Cycle, the runtime engine reflects through your code to search for an appropriate method for that event, just in case it happens to exist, whether you create a handler method or not. To make matters worse, it is reflecting for each event twice, once for a method with handler method arguments (object sender, EventArgs e), and once for a method without the arguments.

There are ten Life Cycle events on the Page that are eligible for auto-wire (counting the Pre-and Post-Events such as PreInit and InitComplete) and four on the Control; for a single page with five user controls, .NET Reflection is searching for up to 60 different methods. That is a lot of run-time overhead! Needless to say, AutoEventWireup can have a significant negative impact on page performance.

Manual Event Wireup

Page events can also be wired manually. This is similar to wiring up any other .NET event. Using manual wire, you must explicitly wire the events you need to the appropriate event handler. However, since you controls the wiring, this allows you to follow any naming convention you wish and if needed, to wire multiple handlers to an event. Just remember to turn AutoEventWireup off.

1

<%@ Page AutoEventWireup="false" %>

Page Events can be wired to their handler within your page's constructor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

publicMyPageClass(){Init+=InitializePage;Load+=LoadPage;}protectedvoidInitializePage(objectsender,EventArgse){//Do some stuff}protectedvoidLoadPage(objectsender,EventArgse){//Do some stuff}

Disadvantages of Using Manual Event Wireup

There is a little extra work involved to manually wire events. For the two events from the auto-wire example, add a constructor and two lines of code. However, this can be a bit of a daunting task if performed against an existing ASP.NET application with dozens of pages and dozens more user controls. Even on new applications, it can be easy to forget to wire the event, though it is easily identified in testing since without the wireup, the handler does not execute, and in most cases, the page does not function properly.

Another disadvantage is that AutoEventWireup is enabled by default in C# (it is turned off by default in VB.NET). Even if you manually wire the events to handlers in the page constructor, you must remember to disable wireup in the Page Directive. Failure to do so will cause ASP.NET to wire up the events automatically in addition to the manual hookup, and the event handler will be executed twice. So, again, don't forget to turn off AutoEventWireup.

Balancing Effort with Performance

Using AutoEventWireup essentially comes down to the value of developer effort versus end-user performance. Auto-wirirng will save developers from one line of code per event, but at the cost of system performance due to the reflection that occurs to have the system wire the events rather than the developer. For a small utility web site or a demo for a presentation, I can understand using auto-wire. However, being a performance guy, I want to extract every ounce of horsepower I can out of my web applications, so I will always opt for manual wiring; with it only costing me one line of code, I feel that it is a good habit to have.