I have a simple timer method in vb, that currently does nothing, it just ticks. Once it does however, all my other code on the page stops working.
as an example, I have image buttons on my page that add controls to a static place holder.
btnCreate.Text = "Create"
btnCreate.ID = "btnCreateSpecialNotes"
AddHandler btnCreate.Click, AddressOf btnCreateSpecialNotes_Click
plhCreateSpecialNotes.Controls.Add(btnCreate)
so without the timer.tick method, that (along with other code not included) would fire off as expected and do what I want, but when the timer.tick happens, everything sort of freezes and nothing works.
My timer is set up as follows
<asp:Timer ID="specialNotesTimer" runat="server" Interval="2000" ontick="specialNotesTimer_Tick"></asp: Timer>
and in the code behind...
Protected Sub specialNotesTimer_Tick(Byval sender as object, Byval e as eventArgs) Handles specialNotesTimer.Tick
'Do things to the page
End Sub
DISCLAIMER: I have never used the System.Web.UI.Timer class.
I think there might be some confusion between client side javascript code and server side C# code.
After reading MSDN, it seems that the Timer control would initiate a full postback every 2000 milliseconds (2 seconds because you say so above). This can only be done in javascript and there needs to be a server side event handler that will perform some task on the server (you call it specialNotesTimer_Tick).
Now, if this task takes longer than 2 seconds to execute, I would assume that you will never see any information on the web page because it would constantly be postbacking (posting back?) and refreshing the screen.
Suggestions:
Reconsider your approach for using a timer
Increase the timer interval
Add an UpdatePanel so the processing happens asynchronously, thus avoiding the screen refresh
Hope this helps.
I think the main problem I had here was the flow of my html wasn't ending. I restarted my page from scratch slowly, and though I used virtually the identical code, I just triple checked all my close tags and what not in html, and that seemed to solve the problem itself.
I'm sorry there isn't a more in depth answer, but I still don't understand why my old code here wasn't working, but re-doing my page from square one worked for me.
Related
I have a page that I've been using that pulls a lot of data for people to see. The data updates about every minute... So to decrease server load I cache the page for 60 seconds:
'-----Set Cache
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Server)
Response.Cache.SetValidUntilExpires(True)
'---------------
That was working great... but now I added an asp.net Timer and set the interval to 30 seconds for testing.
I have a timestamp on the page and when the timer.tick event happens and updates the updatepanel, the timestamps are changing.
Protected Sub tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmr.Tick
updatePanel.Update()
End Sub
Prior to the timer, the timestamps would stay the same on a browser refresh because the cache. Now it appears they're updating on each tick event (eliminating the purpose of caching).
Even in 2 browsers side-by-side, the timestamps are updating on EVERY update by each browser...
So it appears that the timer loses the cache and defeats the purpose.
Does anyone know how to solve this issue?
The page does not have any controls (buttons, dropdowns, etc) it just displays data in grids (multiple instances of user controls inserted programatically).
What you've added - basically caches the GET request for the page. The POST (when the timer fires) typically isn't cached. I'd suggest that you not cache the actual page, but the results of your 'a lot of data'. Please take a look into HttpRuntime.Cache
Should I use HttpRuntime.Cache?
Is it a "Best Practice" to always use .IsPostBack in the Page_Load sub routine of a web form like in this example coding?
I hope it's ok to ask this question. If not, I will immediately remove the question.
Basically I want to code the way most of you are coding.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
' More coding will go here.
'--------------------------
End If
Please give pros and cons for it's usage.
It's not so much a case of "Best Practice" but more a case of whether you need to use it at all.
It's true, you would normally put IsPostBack in the Page_Load, though you could also put it in the Page_Init - basically in any of the page events that fire before rendering out the HTML.
You're essentially using the command to, in this case, prevent the code in the body from firing when the page posts back to itself; such as a form submission or AutoPostBack on a server control, for example the DropDownList.
There aren't any, at least that I can think of, pro's and con's. Its a case of need or don't.
An example of when you would ideally need it would be only wanting to get data from the database once and bind it to a DropDownList. This data would be available in the viewstate when you postback. so you wouldn't need to visit the database again on postback.
An example of when you wouldn't put code in it is if you were generating server controls (button for example) that have an event handler, such as click, added at the same time. this would need to be re-generated on postback for the event handler to be available.
The benefit is that you can do your expensive operations only once. Binding to gridView...etc.
Mostly stuff you do not want to perform during a refresh.
It always depends on what you want to optimize. If your initialization code takes a long time, it is better to do it only the first time and let your controls be initialize through ViewState. Then you use If Not IsPostBack.
But if you target for mobile devices where bandwidth is more important, you might turn of the ViewState and initialize your data again on postbacks (you could read it from Cache or from SessionState). Always watch your ViewState, I have seen pages with 20 kByte ViewState or more.
Pros:
less overhead for initialization (e.g. access to database)
less memory on server (session or cache)
Contra:
more bandwith for ViewState
I'm new to web development, and I'm currently using ASP.net. I wonder what would I need to do to let the browser wait for 3 seconds so my users can read the text "Customer Successfully Added" before turning to another page? I have attached my code as follows.
Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Dim db As New DatabaseClass
db.addProfile(txtLN.Text, txtFN.Text, txtUsername.Text, txtPassword.Text, txtAddress.Text, txtZip.Text, txtPhone.Text, txtEmail.Text)
lblMessage.Text = "Customer Successfully Added"
End Sub
In addition, I'm not sure how to utilize MSDN. For me, its information overload, I'm wondering how to go about finding the solution on MSDN so i would be able to solve my problems in the future. Thank you!
You can't do it in the code behind of the page because of how asp.net works - the label text would not update until after the timeout occurred if you did it in the code-behind.
The server-side processing spits all the html back to the browser only after it has completely processed any server-side code unless you're using Ajax. Since you're new, I won't even bother going into how to do it with Ajax as there is a MUCH simpler option for accomplishing what you want.
A simple method to accomplish what you're looking for would be to have a simple HTML page that just has a message that says "Customer successfully added" and use javascript (client-side code) to pause and then redirect using the Javascript "SetTimeout" function.
There's an example here: http://www.bloggingdeveloper.com/post/JavaScript-Url-Redirect-with-Delay.aspx
The logic flow wshould work like this:
The original page should add the record (in code-behind) then redirect to this simple html page (in code-behind). The html page should have the "Customer Added" message and use the SetTimeout and Redirect to go to whatever page you want the user to see after viewing the message.
For stuff like this you need the code to run client side rather than on the server. The easiest way to do this is to return some javascript with your page (in the .aspx part rather than the code behind)
Take a look here for an idea of what to do :)
The page is displayed for a few seconds and then the javascript triggers a redirect to a url of your choosing. Just add something like this into your html.
You can emit javascript to redirect to the other page, using the setTimeout function.
This is best accomplished using the ScriptManager to register any javascript on the page.
In ASP.Net, I want to run some code (logging, other cleanup) after the page has already been sent to the user. I don't want this code to interfere with the amount of time it takes the client to receive a response. I tried placing this code in the OnUnload part of the page, but through testing (using breakpoints, or busy waiting loops) the client does not actually display the page until the code in the OnUnload is finished executing. Even though the response object is no longer available at this point, and therefore I would assume that the buffered response has been sent to the client, the client still does not display the page until the OnUnload is finished executing. The only way that seems to work at the moment is to start a new thread to do the work, and allow the OnUnload to finish immediately. However, I don't know if this is safe or not. Will the server kill the thread if it executes too long after the page is already sent out? Is there a more correct way to accomplish this?
Kibbee,
Try overriding the Page.Render method and flushing the response like so:
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
MyBase.Render(writer)
Response.Flush() ' Sends all buffered output to the client
' Run some code after user gets their content
End Sub
I think at this point the response still isn't complete, but the user will get what the page has rendered before you finish running that final code.
HTH,
Mike
Unload is the last part of the ASP.NET page life cycle. See link below:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Is this something you could do with javascript or AJAX?
How about hooking into the page.Disposed event instead of the Unload event?
Depending on what you need to do an ISAPI filter can be created to do stuff at the end of the response.
You could try this solution - Best ASP.NET Background Service Implementation
Using a windows service and communicating with it through MSMQ might be a far more reliable solution and can scale up better. This will help you separate the concerns and let asp.net front end just focus on the user while the windows service focusses on the background tasks.
If you are moving to the cloud with azure, you can simply replace the asp.net front end with a web role and the windows service with a worker role and ur solution can scale seamlessly!
Here's a redneck way to do it. Have a second aspx page that does all your "clean up" post-rendering logic. Call that one 'cleanup.aspx' for example. Have your clean up code run in Page_Load of cleanup.aspx:
public partial class cleanup: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// do logging blah blah here....
}
}
In your main aspx page, have a JavaScript function that makes an AJAX call to 'cleanup.aspx'. Make the AJAX function fire after page load. I recommend jquery, if so your code will look like this:
$(function(){
yourAJAXYFunctionName();
});
function yourAJAXYFunctionName()() {
// ajax code here
//
$.ajax({
url: "cleanup.aspx",
});
}
This way, your first page's code runs, then the page is sent to the browser. As the page renders to the client, the 2nd ASPX page is called via AJAX, which really doesn't matter to cleanup.aspx, it doesn't care how its called and its page load event is executed. Your cleanup/logging code is then ran.
Caveats: client side JavaScript is required. But really who the hell doesn't have JS running anyway? Also, your cleanup.aspx page is totally abstracted from your main page, so if you want to use any object in cleanup.aspx that originated in your first page, then you'll have to store them in session or cookies, or you can pass them as parameters in the AJAX call. That will require dynamic manipulation of the AJAX script itself, but that's not too hard.
Better i think try try{Response.End()}catch{} runcode();
I am having a strange problem. Here is the scenario
Here are my files:
Project1.aspx
Project2.aspx
They are set up the exact same, including their Page_Load functions:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If (Not Page.IsPostBack) Then
setPrevIndex(-1)
...
End If
End Sub
They are both set up this way.
Here is where I am running into a problem. When I navigate to either of these pages, i need to make sure that prevIndex is set to -1 (via the function).
For Project1.aspx when I navigate
to the page, the Page_Load fires.
For Project1.aspx when I refresh the page, the Page_Load fires.
For Project1.aspx when I press "Go" in my browsers navigation bar, traveling back to the current page, the Page_Load fires.
For Project2.aspx when I navigate
to the page, the Page_Load fires.
For Project2.aspx when I refresh
the page, the Page_Load fires.
For Project2.aspx when I press
"Go" in my browsers navigation bar,
traveling back to the current page,
the Page_Load doesn't fire at all! The function isn't even
called.
Any ideas why??? What would cause this?
Please ask for clarification.
Update:
When I press "Go" in the URL pointing to the same URL, it seems like the masterpage is the only thing that re-loads, but the Load_Page event doesn't even fire...
Any other suggestions?
Thanks,
E
Try disabling output cache and see if the problem still occurs:
<system.web>
<caching>
<outputCache enableOutputCache="false"/>
</caching>
<system.web>
Use LiveHTTPHeaders or Fiddler to make sure the page is actually being requested the same way each time. This may be an issue with caching.
Load up your website locally and go to http://yourwebsite/trace.axd
This shows a server trace for each page, along with the server status. It also shows the complete page lifecycle with timings.
Clear the current trace and then repeat your 3 visits and reloads each to Project1.aspx and Project2.aspx
What does trace.axd show now? You should have 6 entries, each with the status code of 200 and the verb GET.
If you have fewer then your problem is caching of some sort.
If you have 6 then check the details for the last one - what does is show for the page event lifecycle? It will also show the complete WebForm control hierarchy, so if this related to the master page you will be able to tell.
Try Setting the previndex to -1 in Page Init Event. I am not sure why this is happening though.
Various cache-related things can cause the request not to be made, in particular when you merely press the "go" button, so you should check your cache-headers.
If caching is the issue, you can do something like:
//ask browser to revalidate:
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
//and hint that the page is outdated anyhow...
context.Response.Cache.SetMaxAge(TimeSpan.Zero);
Which should convince a browser to really get a new version every pageview. You could, for instance, set these variables in the Page_Load itself ;-). If you're not using https, then the following are risk-free too:
//prevents plugin based file-open in IE+https, otherwise fine:
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetNoStore();
I'll bet this solves it - and if not, I second Jeremy Steins suggestion that you use fiddler to verify that the request is really being made at all (and since you're a web-dev, get fiddler in any case, it's a handy tool to have available, and works for all browsers!).
Finally - can you tell whether any other code on the page runs when you click go? (i.e. is the entire page not running, or just Page_Load - the latter would suggest an event wire up error, which would be odd considering your load handler does sometimes fire).
It sounds like your page is cached. This would cause the Page_Load not to fire. Check that you have not set that anywhere.
Have you tried publishing the application to a different machine? It could be IIS doing something so try and eliminate that first. Assuming that your code is identical in both na only the page names differ (do a diff on the aspx and .cs files to verify) then move your application to a different server and re-test.
If it is still occurring the it really must be your browser doing something probably with respect to caching.
Try to recreate the scenario with stripped down functions on your server. If the problem persists, try to use some cache-countering methods. If not, that means it has to be your code.
If you have this (or similar) at the top of your page (or master page) this will cause it:
<%# OutputCache Duration="3600" VaryByParam="none" %>