What's Wrong With This Code? (#11)

Wednesday, February 7, 2007
Joe Developer is tasked with displaying the start date of his ASP.NET application. Joe thinks he'll just add a DateTime field to global.asax and initialize the field during the Application_Start event.

<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e)
    {
        StartDateTime =
DateTime.Now;
    }
    
    
public DateTime StartDateTime;
          
</script>

Whenever Joe needs to display the application start date, he accesses this public field.

Joe doesn't know what is wrong, but he is sure of one thing – the date that is displaying on his pages is not the date when the application started. Can you help out Joe one more time?


Comments
Rory Primrose Wednesday, February 7, 2007
My initial thought is that it is an instance/scope problem. Making StartDateTime a static should get around that, but kinda ugly. Why wouldn't you use application state?
Eric W. Bachtal Wednesday, February 7, 2007
Not sure I've ever tried to establish instance data during HttpApplication start, but was still surprised to read this:

"You should set only static data during application start. Do not set any instance data because it will be available only to the first instance of the HttpApplication class that is created."
Tyrone Wednesday, February 7, 2007
A public instance variable in the Global.asax does not translate to mean that you can access this variable globally from anywhere in your application. You would have to add it to the application state bag in order to retreive it from anywhere in your application.
scott Wednesday, February 7, 2007
Rory and Eric:

Making the field static would get the code working - but why? :)

Tyrone:

You can get to fields, properties, and methods in global.asax. In an ASP.NET 2.0 web site you actually get a strongly typed ApplicationInstance property on the page that will reference an instance of the class that represents global.asax, so I could write "ApplicationInstance.StartDateTime" to fetch the value.

Notice I say "an instance" of the class. There is more than one instance alive, but only one of those instances will have StartDateTime initialized to the proper start time.
Eric W. Bachtal Wednesday, February 7, 2007
I assume it's because HttpApplication objects are created when needed, pooled, and reused. On any given request you might get the instance that was created with the first request and populated with instance data during the one call to the start event, but more likely you'll get another instance that never got a start event.
Chris D Wednesday, February 7, 2007
I didn't double check to verify, but i'm pretty sure code inside Application_Start is going to re-run every time the app_pool recycles as well, resetting the date.
scott Wednesday, February 7, 2007
Chris: That's correct. Let's say this is what Joe wants (the date and time when the application was lauched).

Eric: Correct. The code in global.asax ends up inside a class derived from HttpApplication. There will be multiple instances of this class in a pool to serve requests, and this is why using the static keyword with that field is one way to fix the problem.
Haacked Wednesday, February 7, 2007
I want to know when you plan on giving Mr. Joe Developer the pink slip.
Rory Primrose Wednesday, February 7, 2007
Because static variables are stored in the AppDomain and are therefore always in memory for the lifetime of the application regardless of any instance of HttpApplication (or any other object for that matter). There might need to be some kind of locking mechanism though for when static data is altered (threading issues???).
scott Thursday, February 8, 2007
Rory: True, that is something to watch for.

In this case we'll assume Joe only reads the field after the app starts, so it's thread safe (ASP.NET guarantees Application_Start is only called once).
Rick Strahl Thursday, February 8, 2007
So what's the actual value (without looking <s>)...

The first instance gets assigned a value because it's the only one that actually fires Application_Start. All others get what? DateTime.MinValue?

Actually I would argue that putting any properties on HttpApplication is a bad idea precisely because of the confusion about lifetime of HttpApplication, but also even if you use a static you can only reference it directly through this particular class. If you use context.ApplicationInstance the var won't show up (even a public instance variable won't) because the instance is cast to HttpApplication.

For statics that are 'application' level I'd recommend using a separate class - I tend to use App. I hang things like a global configuration object off off that App.Configuration, App.APP_NAME, App.EMPTY_DATE, App.StateLookupTable etc. are then accessible anywhere.

scott Friday, February 9, 2007
Rick:

Yes, when left untouched it comes out as DateTime.MinValue (1/1/0001). I do agree about staying away from HttpApplication.
Jeremy Simmons Tuesday, March 6, 2007
Create a singleton object in your application to store the objects you absolutely have to ensure are only there once using the Singleton pattern.
msdn2.microsoft.com/en-us/library/ms998558.aspx
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!