IIS turned off my application automatically? - asp.net

I just noticed that IIS turned off my ASP.NET web application automatically after it idled 20 minutes. The website is hosted on Godaddy.com.
Below is the Global class which logs the Application_Start and Application_End methods. And the image I uploaded is the result that I saw.
It turned off at 2013-05-24 06:42:40 after the last call I did at 06:22:01. (20 minutes, hua...)
After one day, I did another call at 2013-05-25 03:05:27, the website was awakened.
Strange? I didn't want my website to sleep. Is there any way to keep it sane all the time?
public class Global : HttpApplication
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
log.Debug("Application_AuthenticateRequest -> " + base.Context.Request.Url);
}
protected void Application_End(object sender, EventArgs e)
{
log.Info("Application_End");
}
protected void Application_Start(object sender, EventArgs e)
{
log.Info("Application_Start");
}
}

The IIS/asp.net is turn off the application if you do not have any request for some time to save resource.
Now this usually handle on server side if you wish to avoid it, but in your case you can't interfere with the IIS setup, so one trick is to create a timer that reads every 10 minutes or so one page.
You start it when application starts, and do not forget to stop it when application is go off.
// use this timer (no other)
using System.Timers;
// declare it somewhere static
private static Timer oTimer = null;
protected void Application_Start(object sender, EventArgs e)
{
log.Info("Application_Start");
// start it when application start (only one time)
if (oTimer == null)
{
oTimer = new Timer();
oTimer.Interval = 14 * 60 * 1000; // 14 minutes
oTimer.Elapsed += new ElapsedEventHandler(MyThreadFun);
oTimer.Start();
}
}
protected void Application_End(object sender, EventArgs e)
{
log.Info("Application_End");
// stop it when application go off
if (oTimer != null)
{
oTimer.Stop();
oTimer.Dispose();
oTimer = null;
}
}
private static void MyThreadFun(object sender, ElapsedEventArgs e)
{
// just read one page
using (System.Net.WebClient client = new System.Net.WebClient())
{
client.DownloadData(new Uri("http://www.yoururl.com/default.aspx"));
}
}
One note, do not use this trick unless you needed because you create one more thread living for ever. Usually google reads the web pages and keep it "warm", the auto turn off usually occurs if you have a very new site that google and other search engines did not start to index, or if you have one two page only that never change.
So I do not recomended to do it - and is not bad to close your site and save resource, and your site is clear from any forgotten open memory and start fresh...
Similar Articles.
Keep your ASP.Net websites warm and fast 24/7
Application Initialization Module for IIS 7.5
Auto-Start ASP.NET Applications (VS 2010 and .NET 4.0 Series)

Related

ASP.NET Custom SQLite DeleteExpiredSessions()

The SQLiteSessionStateStoreProvider.DeleteExpiredSessions() is not running automatically on the IIS 7 at any interval. I understand that if my database for session state storage were on inProc, it would be managed automatically at runtime, and if it were on an actual SQL database, there would be a script that would be ran by the SQL agent on an interval to clear expired sessions. However, my issue is that despite having the function defined in the library supplied here: https://github.com/micahlmartin/SQLiteSessionStateStore (renamed to DeleteExpiredSessions() and made public) I am unsure how to have the IIS server call this function, or if I need to implement a scheduled function of my own on the back-end to call this. On the IIS server the session state is set to custom, at 20 minute intervals expiration. It is set to cookie mode, as is the same settings on the web.config for the server. The database is currently holding data from the past 7 days for session states, and I am unsure how to interact with it from the back-end, or if I am missing some service or implementation. Anyone with experience running a custom SessionStateProvider via SQLite through a C# MVC should know how to resolve this, thank you.
Try something like this from your Global.asax:
It runs DeleteExpiredSessions() after about 10 minutes. In the interim it checks every 0.25 seconds to see if the application is shutting down. If it is shutting down then it stops.
public class Global : System.Web.HttpApplication
{
public static Task SessionCleanup { get; private set; } = null;
public static bool ApplicationEnding { get; private set; }
public static void PeriodicallyRunSesssionCleanup()
{
int cleanupInterval = 600000;//10 minutes
int sleepInterval = 250;// 1/4 second
while(!ApplicationEnding && cleanupInterval > 0)
{
Thread.Sleep(sleepInterval);
cleanupInterval -= sleepInterval;
}
if(!ApplicationEnding)
{
throw new NotImplementedException("Place your code that cleans up sessions here to have it run every 10 minutes.");
SessionCleanup = new Task(PeriodicallyRunSesssionCleanup);
SessionCleanup.Start();
}
}
protected void Application_Start(object sender, EventArgs e)
{
SessionCleanup = new Task(PeriodicallyRunSesssionCleanup);
SessionCleanup.Start();
}
protected void Application_End(object sender, EventArgs e)
{
ApplicationEnding = true;
if (SessionCleanup != null) SessionCleanup.Wait();
}
}

How can I programmatically stop the current website? [duplicate]

This question already has answers here:
How can I programmatically stop or start a website in IIS (6.0 and 7.0) using MsBuild?
(3 answers)
Closed 7 years ago.
I am using the MVC5 for an web application. The web app runs in IIS7 or greater.
In the Global.asax on application_start, the number of licenses will be set:
protected void Application_Start()
{
try
{
MyApp.cNumberOfLicenses = COM.GetNumberOfLicenses();
}
catch(Exception e)
{
// log exception
// stop web site.
}
}
If any expection will be thrown in this context, the web site should shut down as you can do that in the IIS-Manager:
How can I stop the current web site in my Application_Start ?
You can do it with the help of "Microsoft.Web.Administration.dll"
using Microsoft.Web.Administration;
After adding the reference of "Microsoft.Web.Administration.dll" write below code in Global.asax
protected void Application_Start(object sender, EventArgs e)
{
try
{
MyApp.cNumberOfLicenses = COM.GetNumberOfLicenses();
}
catch (Exception e)
{
// get the web site name
var lWebSiteName = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
// log exception
// stop web site.
using (ServerManager smg = new ServerManager())
{
var site = smg.Sites.FirstOrDefault(s => s.Name == lWebSiteName);
if (site != null)
{
//stop the site...
site.Stop();
}
}
}
}
I will go not with stop it, but to show some message if you do not have license.
This is an example, and an idea.
You can use this code on global.asax where if you do not have licenses the moment you start, you open a flag, and after that you do not allow any page to show, and you send a page that you can keep on an html file.
private static bool fGotLicense = true;
protected void Application_Start()
{
try
{
MyApp.cNumberOfLicenses = COM.GetNumberOfLicenses();
}
catch(Exception e)
{
// log exception
// stop web site.
fGotLicense = false;
}
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
// if not have license - let show some infos
if (!fGotLicens)
{
// the file we look now is the app_offline_alt.htm
string cOffLineFile = HttpRuntime.AppDomainAppPath + "app_offline_alt.htm";
// if exist on root
if (System.IO.File.Exists(cOffLineFile))
{
using (var fp = System.IO.File.OpenText(cOffLineFile))
{
// read it and send it to the browser
app.Response.Write(fp.ReadToEnd());
fp.Close();
}
}
// and stop the rest of processing
app.Response.End();
return;
}
}
You can have a file named app_offline.htm with content say This website is offline now in web server and copy that to root directoy of website you want for any event.
It will directly show that message, but yes, App pool will be still ON, when you need to start , you just need to rename that to something else.

Call ApplicationStart Method in Global.asax Without a Request

I'm publishing my asp.net site with iis( my local machine has iis v8, server's iis v7 ).
But I want to start a function in Global.asax.cs immediately without calling a page.
*When I call a page, global.asax.cs Application_Start method launches. I want to launch it without a page call request.*
namespace ProductService.XmlFeed
{
public class Global : HttpApplication
{
protected void Application_BeginRequest(Object sender, EventArgs e)
{
FtpUploaderMain.RegisterCacheEntry(); //this method I want to start without page call
}
void Application_Start(object sender, EventArgs e)
{
SimpleLogger.WriteLog("Application Started without a page call","D:\\log.txt");
RegisterRoutes();
//FtpUploaderMain.RegisterCacheEntry();
}
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("Products", new WebServiceHostFactory(), typeof(ProductXmlFeedService)));
}
}
}
You can use PreLoad enabled feature of IIS8 -
For IIS 7.5 use application- initialization -
http://www.iis.net/downloads/microsoft/application-initialization

Url routing Access denied at hosting

I'm using url routing in my asp.net website.I put colde in glocal.asax Application_Start event , void
Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteTable.Routes.MapPageRoute("routedetail",
"alllist/special/{Name}",
"~/sub/mydetail.aspx");
RouteTable.Routes.MapPageRoute("routelist",
"alllist/special",
"~/sub/mylist.aspx");
RouteTable.Routes.MapPageRoute("routehtml", "alllist/myhtml.html", "~/sub/to.aspx");
}
Every thing is ok in my local development and iis7.The error is at online hosting
"routehtml" is not work.Access denied occour.Is it for .html extension ?How can i solved this problem.any suggession..
Try putting that into global.asax
void Application_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if(app.Request.Path.IndexOf("FriendlyPage.html") > 0)
{
app.Context.RewritePath("/UnfriendlyPage.aspx?SomeQuery=12345");
}
}
You may want to check that your IIS 7 Application Pool is in Integrated mode on your host server. It will not work if it isn't.
Although you wouldn't need it, but you could also set RouteExistingFiles property to false at the top of your Application_Start event.

How to Prevent Session Value Reset of Global.asax file in asp.net?

I have about 10 Session variable for storing the File Download Counts of each different 10 Categories wise. I dont know why? but my session variable that is set into Global.asax get RESET automatically.
Since, the Machine is not restarted. Still the Counter of File Downloads get Reset. Any Idea? Plz Suggest me any solution.
In Global.asax:
void Application_Start(object sender, EventArgs e)
{
Application.Add("MGM",0);
Application.Add("PC",0);
Application.Add("NC",0);
Application.Add("TC",0);
Application.Add("PGC",0);
}
The *shortCode* parameter is name of Global Session from Global.asax file. that i am passing to get the counter and increment accordingly.
In Download.aspx.cs Page:
private int GetCount(string shordCode)
{
int count=0;
count = Convert.ToInt32(Application[shortCode]);
lock (Application[shortCode])
{
Application[shortCode] = ++count;
}
return count;
}
Shall i store value in textfile and update accordingly after certain count say 500. if yes how to do? Our colleague says that if suppose many users downloading file and if both access the same value from textfile then cuncurency may occurs.I am Confused...!Help Appreciated.
Please refer to the MSDN page for ASP.NET Application State
Excerpt:
Because application state is stored in server memory, it
is lost whenever the application is stopped or restarted. For example,
if the Web.config file is changed, the application is restarted and
all application state is lost unless application state values have
been written to a non-volatile storage medium such as a database.
By default, ASP.NET applications running on IIS will have their application pool shut down during periods of inactivity. I believe the default value for this is 20 minutes. Also by default, applications pools are recycled every 1740 minutes (29 hours).
When this happens you will lose anything in the Application[] collection that you haven't stored in a more permanent location, such as a database.
Both of the above-mentioned values can be modified by right-clicking on the specific application pool in inetmgr and clicking on Advanced Properties to bring up the appropriate window.
ok good!,
Please try my simple app,four you problem:
protected void Application_Start(object sender, EventArgs e)
{
Application.Add("MGM", 0);
}
protected void Session_Start(object sender, EventArgs e)
{
Application.Lock();
Application["MGM"] = System.Convert.ToInt32(Application["MGM"]) + 1;
Application.UnLock();
}
protected void Session_End(object sender, EventArgs e)
{
Application.Lock();
Application["MGM"] = System.Convert.ToInt32(Application["MGM"]) - 1;
Application.UnLock();
}
protected void Application_End(object sender, EventArgs e)
{
Application.Clear();
}
and you method i changed:
private int GetCount(string shordCode)
{
return Convert.ToInt32(Application[shortCode]);
}
Ok,great i answer this Q,and try change your method:
Startup your web app:
protected void Application_Start(object sender, EventArgs e)
{
Application.Add("MGM",0);
Application.Add("PC",0);
Application.Add("NC",0);
Application.Add("TC",0);
Application.Add("PGC",0);
}
and changed your get count method logics:
private int GetCount(string shordCode)
{
//current app instance
var currentApp = HttpContext.Current.ApplicationInstance.Application;
//get item count
var count = Convert.ToInt32(currentApp[shordCode]);
//locking app for your asking count insrement
currentApp.Lock();
currentApp[shordCode] = ++count;
//unlock app
currentApp.UnLock();
return count;
}

Resources