0

Scenario:

  • I have a ASP.NET 3.5 WebForms based website.
  • It contains Foo.aspx, Bar.aspx and baz.html (jQuery template).
  • Typical traffic seen is Foo.aspx (N times), Bar.aspx (N times) and baz.html (10*N times).
  • ASP.NET worker process (aspnet_wp.exe) is recycled say every 2 hours.
  • There exists an older API (OldFooService.Init()) which needs to be executed only for the first request of Foo.aspx. OldFooService.Init() initializes a data-store into Cache for the very first flow, but fires blanks for subsequent flows.

Question:

I am currently doing B (see below) since the traffic to Foo.aspx is lower than baz.html and OldFooService.Init() fires blanks after the first time.

Should I use C? Writing to Application_State requires locking (MSDN) and its not guaranteed to be available, so not sure if its worth the effort. Or is there a much better D?

Options:

A) In Application_Start of Global.asax

B) In Page_Load of Foo.aspx once (by checking Not IsPostBack)

C) Option B + use a flag in ApplicationState to run once per recycle of aspnet_wp.exe.

Channs
  • 2,091
  • 1
  • 15
  • 20
  • 1
    The answer seems extremely obvious, A. I'm curious why you are hesitating and decided to ask on SO? – EkoostikMartin Jul 11 '12 at 13:34
  • Updated my question. The older service needs to run only for the very first request of Foo.aspx. Since the traffic is higher to baz.html and also aspnet_wp.exe is recycled constantly, which doesn't require the older service, I am hesitant to initialize in Global.asax. – Channs Jul 11 '12 at 13:35
  • 1
    Application_Start only fires once, when the worker process starts, doing this once every 2 hours doesn't seem bad. What type of Cache are we talking about? – EkoostikMartin Jul 11 '12 at 13:42
  • The older service uses HttpContext.Current.Cache. – Channs Jul 11 '12 at 13:46
  • How large of a cache are we talking about? From start to finish, how long does it take your OldFooService.Init() to run? What's the memory footprint? – Jaime Torres Jul 11 '12 at 13:47
  • You could wrap the cache in a class and lazy load it, but I still think Application_Start is the best option. – EkoostikMartin Jul 11 '12 at 13:57

2 Answers2

4

The correct answer here is (A), use Global.asax. B won't work as subsequent GET requests will run the same code. C will work, but is ugly as sin.

I would recommend handling Application_Start or Application_Init in Global.asax, depending on what's required in your legacy init function.

Jaime Torres
  • 10,365
  • 1
  • 48
  • 56
  • Thanks for the answer. Sorry, I didn't word my scenario correctly. The older service needs to run only for the very first request of Foo.aspx. Since the traffic is higher to baz.html and also aspnet_wp.exe is recycled constantly, which doesn't require the older service, I am hesitant to initialize in Global.asax. – Channs Jul 11 '12 at 13:37
  • The question is, is N > 1 (number of times Foo.aspx is accessed) during the 2-hour lifecycle of your worker process? If so, it still makes sense to locate the logic in Global.asax. Also, why is your worker process recycled so often? – Jaime Torres Jul 11 '12 at 13:46
1

If it's ok for OldFooService.Init() to be called a few extra times in the event of requests coming in simultaneously before its initialized then I would go with C. If it absolutely must run once per recycle, then I would use a static class with some proper read/write locks.

On a side note, is the worker process actually recycled every 2 hours? That seems rather frequent.

Ted Elliott
  • 3,415
  • 1
  • 27
  • 30
  • Thanks for the answer. The frequent recycling is just a side-effect of automated builds to dev/test environments. I can see how my words paint the wrong context, will take note to avoid this in future. – Channs Jul 11 '12 at 14:06