I am doing this with a background thread that requests a keepalive url every 15 minutes. This not only simplifies the application, but also immediately heats up the application at any time when the web role or virtual machine is restarted or rebuilt.
This is all possible because web roles are really work roles that also use IIS stuff. That way, you can still use all the standard job role hooks in the web role.
I got an idea from this blog post , but changed the code to complete a few extra warm-up tasks.
Firstly, I have a class that inherits from RoleEntryPoint (it does some other things besides this warming task, and I removed them for simplicity):
public class WebRole : RoleEntryPoint {
This WarmUp class uses all the real warm-up logic. When it starts, it types several URLs on the local IP address of the instance (vs public, load balance hostname) to get the information in memory so that the first people use it to get the fastest response time. Then it bypasses and removes one keepalive URL (again in the local instance of the role), which does no work and just serves to prevent IIS from closing the application pool as unoccupied.
public class WarmUp { private Thread worker; public void Start() { worker = new Thread(new ThreadStart(Run)); worker.IsBackground = true; worker.Start(); } private void Run() { var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["http"]; // "http" has to match the endpointName in your ServiceDefinition.csdef file. var pages = new string[] { "/", "/help", "/signin", "/register", "/faqs" }; foreach (var page in pages) { try { var address = String.Format("{0}://{1}:{2}{3}", endpoint.Protocol, endpoint.IPEndpoint.Address, endpoint.IPEndpoint.Port, page); var webClient = new WebClient(); webClient.DownloadString(address); Debug.WriteLine(string.Format("Warmed {0}", address)); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } var keepalive = String.Format("{0}://{1}:{2}{3}", endpoint.Protocol, endpoint.IPEndpoint.Address, endpoint.IPEndpoint.Port, "/keepalive"); while (true) { try { var webClient = new WebClient(); webClient.DownloadString(keepalive); Debug.WriteLine(string.Format("Pinged {0}", keepalive)); } catch (Exception ex) { //absorb } Thread.Sleep(900000); // 15 minutes } } }
source share