What is the best way to measure the code run time in ASP.NET page?
Here is my code, trying to time the page load and writing to log.
private Stopwatch PageTimer = null;
protected void Page_Init(Object Src, EventArgs E)
{
if (!IsPostBack)
{
PageTimer = new Stopwatch();
PageTimer.Start();
}
}
protected override void OnPreRender(EventArgs e)
{
if (!IsPostBack)
{
PageTimer.Stop();
Logger.SectionEnd("PageTimer", PageTimer, "", true);
}
base.OnPreRender(e);
}
You may try mvc-mini-profiler.
I'd recommend you use a HttpModule for that. There's one you can use at
HttpModule For Timing Requests
(pretty old, I know, but still valid)
A good thing about HttpModules is that you have them self-register themselves if the "main application" has code for it. Using a module in another application is then just a copy paste in to the bin folder and it will start to operate.
If the "main application" doesn't support modules to self-register it can be added to the bin and web.config to start operating.
If you'd like something simple and fast i suggest using the global.asax file.
You can create this file by selecting new file in a website.
The global.asax file has a few methods, the ones you should be looking for are
Application_BeginRequest
Application_EndRequest
You could start a timer, write some logging , do whatever to get the time between these 2 requests.
By doing it like this you have the exact time the request spent on your server, if you do it in the page_load and page_prerender you miss out on stuff like redirection, authentication, membership etc
Here is another choice: Web Performance Test Using Visual Studio
If you exclude logging, you can use firebug to measure client-side performance.
Related
I have two questions. I will split my questions into two sections and give an overview. I'm not entirely sure of the code I need to post so if I have missed some out, please let me know and I will help.
Overview:
When the browser is closed I need to sign the user out.
Question 1:
How do I call Session_End when the browser is closed?
I did some reading on how to close it and it seems that the only way to detect if a Session has ended when a browser has been ended is by using something called 'InProc' in my web config. I gave it an attempt and it didn't seem to change anything at all. So I'm wondering if there is another way around this.
Session_End:
protected void Session_End() {
if (User.Identity.IsAuthenticated) {
}
}
Question 2: How to sign a user out on Session_End?
Once the program has called the void I need to sign the user out as it's causing a bug in my program. I am using the Authentification manager.
Session_End:
protected void Session_End() {
if (User.Identity.IsAuthenticated) {
AuthenticationManager.SignOut();
}
}
Using InProc sessions, the Session_End method is called when the session times out. This is (by default) 20 minutes after the user has last accessed your site (requested a new page). Note that these 20 minutes could have been spent carefuly reading a single page of your site - his session is still closed.
There is no way to detect when a user has closed his browser or navigated away from your site.
You need to use the Global.asax file. It should already contain this Method, all you need to do is add the guts of your code.
protected void Session_End(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
AuthenticationManager.SignOut();
}
}
Is theire a way, to get noticed if an asp.net web forms session is droped (For example, the client cloeses the browser = timeout)?
We have one session for the temporary user shopping card:
HttpContext.Current.Session["UserShoppingCard"] = new UserShoppingCard();
Every thing works fine, besides the functions explanied above.
Thank you!
I would try to intercept the Session_End event in the global.asax file and put some logging in there, it might not happen right when the browser is closed but it will happen at some point anyway once the session is terminated and you can include your logic in there.
In fact the server never knows when a browser is closed or if instead a connection issue is making the client unable to connect.
As said before, complementing with code...
public class Global : System.Web.HttpApplication
{
protected void Session_End(object sender, EventArgs e)
{
//Do your things here when session ends...
}
}
I'm currently using the "Session_Start" function within the Global.ascx file to save when an authenticated user visits my site.
This works OK if a users session expires, however as I'm using persistent cookies the user may return to the site within 28 days and this function will not be called and therefore will not be recording in the database that the user has visited.
I've taken a good look at all the functions available within Global.ascx, however I cannot find one that will perform what I need.
Application_Start - triggered only run within life cycle
Application_BeginRequest - each and every request made
Application_AuthenticateRequest - each and every request
Session_Start - when a new session is started
The two events that I believe could be used are Application_BeginRequest or Application_AuthenticateRequest.
Is there any way of limiting the above events to only run specific code on the first visit to a site and not on each request?
Alternatively is there any way of using my master file?
Any suggestions would be very useful.
Cheers
Why don't you implemented by your own? As you mentioned there is an event Application_BeginRequest. I think following might do the trick:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string session_param_name = "SOME_SESSION_ID";
if (HttpContext.Current.Request.Form[session_param_name] == null)
{
//Count
}
else if (HttpContext.Current.Request.QueryString[session_param_name] == null)
{
//Also count
}
}
I have an .aspx page with some synchronous code that's taking a very long time to execute and is triggering a request timeout. For example:
protected void Page_Load(object sender, EventArgs e)
{
var log = LogManager.GetLogger("test");
log.Debug("Before thread sleep...");
Thread.Sleep(99999999);
log.Debug("After thread sleep.");
}
In my Global.asax, I've added some error handling that will e-mail out any exceptions:
protected void Application_Error(Object sender, EventArgs e)
{
var exception = HttpContext.Current.Server.GetLastError();
SendExceptionEmail(exception);
}
Problem is, in Global.asax, I only have access to the request and response and the exception that occurred, but not the output from the logger. How do I get access to this in Global.asax? Without it, I can't tell what piece of code is hanging the application without digging through the log files, which is a major chore to filter.
The 'log' object is a static variable, and it is not correct to try to fetch it in Global.asax Application_Error(). Depending on the current thread in thread pool, you might get unpredictable values in it.
A more secure approach could be along with log.Debug() to insert some Debug data into HttpContext.Current.Items. Then you can access these items in Application_Error() method.
Context.Items are considered as thread-safe and are recommended for use in cases like this.
Another way to do it would be to have log4net send the email for you using an email appender. See this example: http://sradack.blogspot.co.uk/2007/09/have-log4net-send-email-when-error.html
I have over 30 aspx pages, i have discovered a problem recently that if i did any kind of database transaction like insert, update, delete and then after the transaction is complete i pressed F5 or refreshed the page in anyway the same is transaction occur.
I searched for a solution but all i could found is that i have to check for viewstate on each button which is impossible, cause that means there will be a lot of work. There got to be generic solution, please help me in this problem.
Edit:
Here is the code on one of the buttons which change a value in data base to either true or false:
protected void btn_Publish_Click(object sender, EventArgs e)
{
if (Convert.ToBoolean(int.Parse(hf_Published.Value.ToString())))
{
publish(false);
}
else
{
publish(true);
}
}
After the execution of the code if refreshed the page the same code is executed, i noticed that since a break point was placed on this method.
You can try this. I used this in several project and working successfully.
public bool IsRefreshed
{
get
{
if (Convert.ToString(Session["RefreshTimeStamp"]) == Convert.ToString(ViewState["RefreshTimeStamp"]))
{
Session["RefreshTimeStamp"] = HttpContext.Current.Server.UrlDecode(System.DateTime.Now.ToString());
return false;
}
else
{
return true;
}
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ViewState["RefreshTimeStamp"] = Session["RefreshTimeStamp"];
}
protected override void OnLoad(EventArgs e)
{
if (!Page.IsPostBack)
{
Session["RefreshTimeStamp"] = HttpContext.Current.Server.UrlDecode(System.DateTime.Now.ToString());
}
base.OnLoad(e);
}
There IS a generic solution, used for years by thousands of developers.
And the solution is: each time you perform an intrusive process at the server (insert/update/delete) you don't just render the page but rather you redirect the response with 302 to a fresh page with "your transaction succeeded" message.
This way, pressing the F5 will just refresh this message page, not the original page which triggers the transaction.
It is up to you whether or not this is directly applicable in your scenario.
http://en.wikipedia.org/wiki/Post/Redirect/Get
To fix this issue you could check the following:
Disable the submit button when necessary
Add some validation to your code and check for double entries
Redirect the user to another page after submit
Unless it's a real 'transaction' like payments etc. (which others already explained, do redirect etc.),
You could also try defining caching on your pages that interact with the Db or are bottlenecks for your app.
If you wanna have always live info (and it's that 'alive' type of app) then no luck with that solution (but even then), but usually, you can put some reasonable time expiration on how 'fresh' you want your data to be.
Caching ASP.NET Pages