Is setting the value of Server.ScriptTimeout enough to prevent page timeouts? - asp.net

On an administrative page with a long running process we're setting the following:
protected void Page_Load(object sender, EventArgs e)
{
this.Server.ScriptTimeout = 300;
//other code
}
Is this enough that should prevent that page from timing out as it does what it needs to? I have no control over the process and how long it runs but we've found that 5 minutes is more than enough time, yet we're still getting intermittent errors of:
System.Web.HttpException: Request timed out.
We've tried upping the value to 600 with really no difference and in any testing we've done we can never get the actual process to run for that long. Is there elsewhere that we need to be setting timeout values that won't affect the entire application and only the specific page we need the longer timeout value on?

I think you should never have a "script" that can take up to 5 min to run in Web App ,expecially into the page load! Why don't you create a web service or somethig that wrap this process? then you can use any Async pattern to invoke it avoiding to make the page stack on one the same call
anyway have a look at the link below for more detail about the Default server time out
http://msdn.microsoft.com/en-us/library/ms524831(VS.90).aspx

Related

Forcing an ASP.NET page_load

I have an ASP.NET (4.5+) app that calls an asynchronous task from Page_Load in order to obtain data for the page. I want to refresh that data every 15 minutes with out any user input.
First I tried using a timer and calling Page.ExecuteRegisteredAsyncTasks() in the timer function. No error but my async task never gets called. Just during Page_Load.
Then I tried various techniques for force a reload of the page figuring that would cause Page_Load to get called again but each attempt resulted in an exception being thrown saying that technique could not be used at that time.
The C# method I want to call every 15 minutes is defined as a private async Task.
What is the best way to call this method every 15 minutes? As I wrote above it is getting called successfully from Page_Load but never again.
You will need to use a worker of some kind. If you had a timer then every time you refreshed the page, the timer would reset, you could use possibly a session variable to keep track. This is just the nature of the page lifecycle.
One alternative is to create a service, you could use an ASMX service for this and pull the data from the client-side. Using HTML5 Local Storage to keep track of the time last updated, or even "nextTimeToUpdate" store 15+ minutes from now. Set a time out of every 1 minute to check the current DateTime and if >= nextTimeToUpdate then trigger the request via AJAX.
Since local storage persists even after the browser is closed, when the user next visits the page and the data will still be there. The data is only lost if the user shuts down their machine/cleans their browser.
Edit
Assuming you want to trigger these events server-side. Move the async task into a new class, instantiate or inject it on the page you want.
Scott Hanselman has an article on How to run Background tasks in ASP.NET. A noteworthy library Hangfire
You have to use Timer, it is best way, I think.
Just follow next steps:
In design page:
<asp:ScriptManager ID="manager" runat="server" />
<asp:Timer ID="timer" runat="server" Interval="900000" OnTick="timer_Tick" />
Then create some function (e.g. MyFunc()), and your code behind:
protected void Page_Load(object sender, EventArgs e){
MyFunc();
}
protected void timer_Tick(object sender, EventArgs e){
MyFunc();
}
protected void MyFunc(){
//do all actions, what you need, here
}

Why does my ASP.NET keep-alive logic not work?

In order to ensure that my session always stays on, I created a simple stayalive.aspx page. The header of the page contains metadata to refresh the page every 5 minutes.
In my page-load logic, I simply set a value into session.
protected void Page_Load(object sender, EventArgs e) {
System.Web.HttpContext.Current.Session["Alive"] = 1;
}
My understanding is that as long as you keep putting a value in the session, the session will continue to stay alive. However, this does not seem to be working. I still get a session timeout in about 30 minutes.
I am wondering if anyone has any insight on why is not working.
Note that the sessionstate as well as forms authentication timeout values in web.config are set to 300 (5 hours).
One thought I had was, instead of setting the same value on the session, I set a different value each time:
System.Web.HttpContext.Current.Session["Alive"] = DateTime.Now;
Do you think this would help?
Adding a value in to the session is not required to session alive. If you keep on refreshing the aspx page, session should automatically extend.

Timer Class in ASP.NET

I have this code in the asp.net application start evert, and I'm not really familar with the Timer class but what I want to do is have one Trigger that goes off every night at 11 pm, one that goes off at 5:30 in the morning and then every hour after that.
private System.Threading.Timer timer;
protected void Application_Start(object sender, EventArgs e)
{
int intervalMilliseconds = 60 * 1000;
timer = new System.Threading.Timer(new System.Threading.TimerCallback(TimedEvent), null, intervalMilliseconds, intervalMilliseconds);
}
protected void Application_End(object sender, EventArgs e)
{
if (timer != null) timer.Dispose();
}
private void TimedEvent(object stateInfo)
{
MyClass.ExecuteCode();
}
*Please no answers in the way of "don't use asp.net to do triggers because of the lifecycle".
*Again - please no posts on what not to use. I've received two post both telling me what not to use and both not related to my question which is about the Timer class and how to use it.
From your question i'm assuming you don't have full control over your hosting environment, so will try to avoid the schedule it... etc answers.
Having said that, you still need to be aware of the asp.net lifecycle, and your trigger approach is fraught with dangers.
Do you get enough traffic that the application won't end unexpectedly? Do you know the configuration of IIS, so recycling is not a worry?
I can see three approaches:
I would recommend having a page, which uses some sort of key, which is only known
by the caller. Have this page triggered by a watchmouse (See: http://www.watchmouse.com/en/), or scheduled crawler on a pc/server which will always be on, at the times you need it to be triggered.
An alternative would be to trigger a database process, which runs when needed to.
Depending on your environment, this can be scheduled too.
Another would be to check a log file, on users accessing the page, and if it is the first access within the hour, trigger your process. (Do this for whatever period you need.)
However this depends entirely on how heavily your site is accessed, and may not work reliably.
When you create your timer and hook up its tick/elapsed event, set the interval to be every 5 minutes or so.
Then in the tick/elapsed event handler, check the current time and perform an action where necessary. Obviously you will also need to record when an actino has been performed so you don't perform it at 10:58 and 11:03 pm.
Have a look at Quartz.NET, which will allow you to set up cron-like triggers.
Maybe a different way of doing what you want: Instead of relying on ASP to be active, perhaps you can just use the windows scheduler to schedule your event. It has more of the scheduling features you want and will be likely be more reliable as well as already debugged. Your timed event can be as simple as accessing http://localhost/YourApp/.aspx. You'll get the same effect with the added benefit that if your app happens to have recycled, your event will still execute as the 1st request.
You can do the kind of thing you're describing by using the inbuilt ASP.NET Cache.Add CacheItemRemovedCallback delegate. It's a bit of a roundabout way of using it, but you can do effective scheduling this way.
There's an article here showing how to do it.
More information on the CacheItemRemovedCallback here.
Edit: I know you said no services, but if you check the server and find you can use Scheduled Tasks, you can use that to run a console app on a specific schedule like some other other answers mention.

Measure ASP.NET page load time

I'm currently developing an ASP.NET application which uses a MasterPage and I want to measure my application webform's loading time and display that information to the client.
My current strategy involves using the Application_BeginRequest event associated callback (in the Global.asax file of my website solution), to start the measurement of the time spent on the server-side process (as follows)
protected void Application_BeginRequest(Object sender, EventArgs e) {
Context.Items.Add("Request_Start_Time", DateTime.Now);
}
and calculate the elapsed time on the webform's OnPreRender event associated callback, printing it on a placeholder element (as follows)
protected override void OnPreRender(EventArgs e) {
base.OnPreRender(e);
TimeSpan tsDuration = DateTime.Now.Subtract((DateTime)Context.Items["Request_Start_Time"]);
ExecutionTime.InnerHtml = "<em>Server-side processing duration: " + tsDuration.TotalMilliseconds + " miliseconds.</em>";
}
is this the best way to measure loading time? Is there a more "elegant" way to accomplish this?
Thanks in advance for your time and cooperation.
<%# Page Trace="true" %> (or set this in web.config)
Enable tracing and check out the information in trace.axd (in the root of your website).
Then you could set timing points with:
Trace.Write("Start time intensive task");
Trace.Write("Stop time intensive task");
http://msdn.microsoft.com/en-us/library/bb386420.aspx
This is assuming "your client" want deep debug data.
Your appproach seems to be exact enough, as long as you do not render very large control trees and you don't use server controls that do all their work in an overridden Render method (unexperienced server control authors tend to do exactly that...).
In that case, there is actually a way to render the actual rendering time ;-) Just use a HttpResponse.Filter object to fill a placeholder with the elapsed time. These filters are applied after the web form is rendered and before it goes to the client.
If you need this just for development, search for trace.axd, this will give you a lot of details not only about timing but also the request context, control tree structure and page size.
This really depends on what metric you are looking to actually show.
Is this an overall "page loaded in __ seconds" type thing that will be there all the time?
Is this to determine if your coded solution meets requirements for a client, and not needed for production?
The answer to these two will dictate what makes the most sense when it comes to recording. If your goal is #1, then I would say your method works. If you are going for number 2, I could be looking at what Erwin has.

How does one discard a session variable while closing Web Page?

We are following a procedure in our work while developing a web page, is to bind page to one or more session variables, these session variables are used only for that page, to hold current processing objects, so while closing page no need for them.
How could I discard these session variables while closing page?
Any suggestions regarding that technique or how to solve that problem?
There is no server-side event that is raised when a page is left/closed. Also the Session_End event (mentioned in other answers) is not called when a page is left, since the user might navigate to other pages of the same web application (and therefore the session will continue to exist).
I can think of 3 possible ways to solve (or work around) this issue:
1 - use ViewState to store data with page-scope. This is what ViewState is made for, and unless you have a lot of data, it should not be a problem. If you have a lot of data, remember, that it will be serialized/deserialized and sent to the client/back to the server for every request (which may result in large requests and therefore bad performance).
2 - instead of putting the data into the session, put it into the Cache (with a low sliding expiration timeout). On your page, you can access your data in the same way as from the session, i.e. data = Cache["data"], but you have to be prepared that the data was removed from the Cache (you have to re-load it again from DB for example), if the time between two requests was bigger than the expiration time.
3 - use the client-side (javascript) onUnload event, and trigger some action (e.g. a ajax callback) to remove the data from the session. But I think the onUnload event is not reliable (it will not be fired in any case, e.g. when the browser is terminated by a crash or with the task manager, or if javascript is disabled).
If you use variables for only that page, store them in viewstate. ViewState is suitable for page scoped variables.
If you are using ASP.NET sessions (which you probably are), you can add a global.asax file to your soluting. In there this event-delegate is to be found (if not, create it):
protected void Session_End(object sender, EventArgs e)
{
}
.. In here you can clear your session collection.
protected void Session_End(object sender, EventArgs e)
{
Session.Clear();
}
This will be fired when the session expires or when a user clicks logout :)

Resources