I have a ASP.NET MVC4 web app, and I want some code to be executed the first time an app starts. The code basically loads a bunch of data from the database and stores it in a cache, so that any future requests can look up the data from the cache.
Where is the correct place to put this code? Should I simply add my line of code to Global.asax, or is there a best practice for calling code once an app starts?
Have a separate class to do the data initialization and call the respective method from Global.asax. The Global.asax should basically serve as an orchestrator. The individual initializations such as DI container initialization, cache initialization, route initialization etc. should sit in their own classes, thus honouring the single responsibility principle.
Global.asax.cs:Application_Start()
Same place you do things like register routes.
This is exactly where I initialize caches as well. I also check the cache expiration time on each Application_BeginRequest() to see if it needs to be updated.
You could place the code in Application_Start in Global.asax.
Or you could use the Lazy type on a static member, and it'll only initialize when it's first called (and it remains in memory for as long as the application runs). This has the advantage of not slowing application start up unnecessarily.
For instance, this example is for a compiled Regex, but could also be done with loading data:
public static Lazy<Regex> LibraryTagsRegex =
new Lazy<Regex>(() => new Regex(#"^library/tagged/(?<Tags>.+)", RegexOptions.Compiled));
Related
I need to download some tables from the database, and create static list classes with the information. I can do this in owin startup, or RoleEntryPoint onStart.
I tried to preload the lists in RoleEntryPoint onStart, however, these classes doesnt seem to be available in the runtime, instead they got created again.
If I preload them in Owin Startup, everything works as it should.
However, it takes about 10 seconds for me to preload these lists, and while owin startup is executing, the Onstart already had been executed and therefore the web role becomes available for accepting requests. I dont want this though. I dont want the web role to switch to ready state until all of the lists are preloaded.
it seems like any instances that are created in RoleEntryPoint arent available in the webrole runtime itself.
Is there any way to achieve preloading instances in OnStart and having being able to use them in the runtime?
RoleEntryPoint is the best way to achieve your requirement.
Define static List variables with singleton pattern in the WebRole.cs.
Implement async repository or private methods to fill them. You do not have to populate your static lists on app startup. According to the singleton pattern, they will get filled on first request.
I use the same approach in my static repository instance initialization of WCF service startup process.
Good luck
We're writing a class we'll use in our asp.net site. This class will pull down some json using HttpClients and such, and use it to provide information to other clients.
Some of this information will change very infrequently and it doesn't make sense to query for it on each client request.
For that reason I'm thinking of making a static constructor in this new class for the slow-changing information and stashing the results in a few static member variables. That'll save us a few HttpRequests down the line-- I think.
My question is, how long can I expect that information to be there before the class is recycled by ASP.Net and a new one comes into play, with the static constructor called once more? Is what I'm trying to do worth it? Are there better ways in ASP.Net to go about this?
I'm no expert on ASP.Net thread pooling or how it works and what objects get recycled and when.
Typical use of the new class (MyComponent, let's call it) would be as below, if that helps any.
//from mywebpage.aspx.cs:
var myComponent = new MyComponent();
myComponent.doStuff(); //etc etc.
//Method calls like the above may rely on some
//of the data we stored from the static constructor call.
Static fields last as long as the AppDomain. It is a good strategy that you have in mind but consider that the asp runtime may recycle the app pool or someone may restart the web site/server.
As an extension to your idea, save the data locally (via a separate service dedicated to this or simply to the hard drive) and refresh this at specific intervals as required.
You will still use a static field in asp.net for storing the value, but you will aquire it from the above local service or disk ... here I recommend a System.Lazy with instantiation and publication options on thrread safe (see the constructor documentation).
i am using .net4.0 framework
i am working on Web Project using c#
i want to make some request which will populate some items in cache beforehand.
Ex.
user comes to the home page of application.
[ i will write some code in Home Page(.ASPX) which will call some method which will read some files from disk and put them into cache though i don't need this cache on home page... at this point as reading files from disk is going to be somewhat lengthy operation... i would to load home page completely without waiting for response from method(which is going to read files from disk)]
Something like
function page_load{
CacheGenerator.CreateCache();//this is going to be heavy operation..i don't want to wait for this operation to complete
repose.write("Hello world:); // this statement should run moment after above function is called
}
and one more thing can we do this without using threading.
Anything asynchronous is "using threading" in one way or another.
More importantly, you should not start any async operation from a page. The page only exists in memory for the duration of the request. Your async operation may complete after the page no longer exists in memory.
You may be able to use the Task class to start an async operation from the Application_Start event in global.asax.
Can you give an example of what might be best suited to place in the Application_Start and Session_Start subroutines?
I know when each subroutine is called.
Application_Start when the first user first accesses the web application.
Session_Start when a user opens a session with the application.
But what code belongs in each of these subroutines. What should the code in each subroutine do?
Just any examples? Well, in an MVC site the routes are registered in Application_Start. That's also a good place to initialize an IoC container such as StructureMap. Maybe initialize some singletons you have in your application if you want them to be readily available rather than late-bound when a user accesses them (like if they have a high initialization cost and you'd rather do one slow initial hit on the website yourself than bother a customer or two with it).
Session_Start is generally used less often, but could be a good place for per-user (or per-session, realistically) tracking of some kind.
Application_Start is often used to initialize application wide settings which need to be done once per application domain like registering object containers, reading some config initialization values, ... In Session_Start you could place some code which is tied to the specific user who started the session.
Be careful with exception handling in Application_Start. In IIS7 Integrated mode you won't have the response object or HTTPContext. See this thread: Request is not available in this context
I have some code that initializes a static singleton class, which is needed by all requests. Therefore I thought I could add it to global.asax Application_Start. Can I be 100% sure that all requests will block while Application_Start is loading to guarantee that all the requests will have access to it?
Thanks a lot
Jeeji
Short answer: yes.
Application_Start:
Called when the first resource (such
as a page) in an ASP.NET application
is requested. The Application_Start
method is called only one time during
the life cycle of an application. You
can use this method to perform startup
tasks such as loading data into the
cache and initializing static values.
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.
http://msdn.microsoft.com/en-us/library/ms178473.aspx