ASP.NET AJAX Timer Trouble? Location is key.
AJAX, ASP.NET, JavaScript, Performance By Dave Ward on September 19th, 2007If you’ve made much use of the ASP.NET AJAX Timer control, you may have noticed that it can behave somewhat unexpectedly. In this post, I’m going to take a closer look at how the Timer works and the most significant factor that influences it: Location.
Where the timer is placed on the page actually varies how it operates. As a Timer’s delay interval approaches the processing time of its resulting PostBack, the difference that the Timer’s location makes becomes very significant.
Warning: Timers and UpdatePanels are a potentially dangerous combination. For long intervals, the simplicity can often be worth the performance trade-off. However, as your interval becomes smaller, you should very seriously consider a lighter weight approach to polling for data updates.
That said, I know that you’re probably still going to be using them even when you shouldn’t. So, let’s take a closer look at how the Timer actually works.
The Timer control’s underlying mechanism
It’s important to understand that the Timer control is simply an elaborate abstraction for combining JavaScript’s setTimeout and ASP.NET’s __doPostBack.
Assuming that UpdatePanel1’s OnLoad event was handled in the same way that the Timer1’s OnTick was handled, a Timer declared like this:
<asp:Timer runat="server" id="Timer1" Interval="5000" />
Could be very roughly approximated by JavaScript such as:
function pageLoad() { window.setTimeout("__doPostBack('UpdatePanel1', '')", 5000); }
There’s nothing magic about the Timer control. It attempts to approximate the Timer control that we’re used to in WinForms development, but is still subject to the limitations of the stateless HTTP protocol.
Keeping this in mind, let’s look at two cases. In both, the Timer will have an Interval of five seconds and will trigger a partial postback taking four seconds to complete. However, due to Timer placement, the actual time between updates in these two cases will differ by around 80%.
Case 1: A Timer inside UpdatePanel content
<asp:ScriptManager runat="server" ID="ScriptManager1" /> <asp:UpdatePanel runat="server" ID="UpdatePanel1"> <ContentTemplate> <asp:Timer runat="server" ID="Timer1" OnTick="Timer1_Tick" Interval="5000" /> <asp:Literal runat="server" ID="Literal1" /> </ContentTemplate> </asp:UpdatePanel>
protected void Timer1_Tick(object sender, EventArgs e) { System.Threading.Thread.Sleep(4000); Literal1.Text = DateTime.Now.ToLongTimeString(); }
This is probably the easiest way of implementing a Timer. You can just drop it in the UpdatePanel, create an OnTick handler, and not worry about setting up triggers or anything else.
However, even though the Timer interval is very clearly specified as five seconds, this UpdatePanel will actually take just over nine seconds for each Tick to fire. The reason for this large discrepancy is the location of the Timer. Take a look at the partial postback response, and it becomes clear why:

Because the Timer is inside the UpdatePanel’s ContentTemplate, it will be reinitialized every time the UpdatePanel refreshes. It actually comes within one second of triggering another OnTick event, but is reset by the partial postback’s return.
This may or may not be desirable in a given scenario, but can be fairly unexpected.
Case 2: A Timer outside UpdatePanel content
<asp:ScriptManager runat="server" ID="ScriptManager1" /> <asp:Timer runat="server" ID="Timer1" Interval="5000" OnTick="Timer1_Tick" /> <asp:UpdatePanel runat="server" ID="UpdatePanel1"> <Triggers> <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" /> </Triggers> <ContentTemplate> <asp:Literal runat="server" ID="Literal1" /> </ContentTemplate> </asp:UpdatePanel>
protected void Timer1_Tick(object sender, EventArgs e) { System.Threading.Thread.Sleep(4000); Literal1.Text = DateTime.Now.ToLongTimeString(); }
Implementing the Timer this way removes the reinitialization interference, but exposes another potential problem. Since the Timer ticks are now fixed at an absolute five second interval, only one second less than our partial postback requires to complete, the UpdatePanel spends nearly all of its time in async postback.
Depending on your application this may be exactly what you want, but it also might be very detrimental to the usability and performance of the application. For example, if you were to locate a one second Timer outside an UpdatePanel that took two seconds to refresh, it would never manage to complete a single update.
Conclusion
As you can see, Timer placement can significantly and unintuitively affect how the Timer actually operates. Understanding all of the influencing factors puts you in control and enables you to arrange your Timers to best suit your application.
I’m going to leave you with a bit of a pop-quiz. I hope you were paying attention! Consider the following code sample, from a question posted on the asp.net forums:
<asp:ScriptManager runat="server" id="ScriptManager1" /> <asp:UpdatePanel runat="server" ID="UpdatePanel1"> <ContentTemplate> <asp:Literal runat="server" ID="Literal1" /> <asp:Timer runat="server" ID="Timer1" Interval="5000" OnTick="Timer1_Tick" /> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel runat="server" ID="UpdatePanel2"> <ContentTemplate> <asp:Literal runat="server" ID="Literal2" /> <asp:Timer runat="server" ID="Timer2" Interval="10000" OnTick="Timer2_Tick" /> </ContentTemplate> </asp:UpdatePanel>
protected void Timer1_Tick(object sender, EventArgs e) { Literal1.Text = DateTime.Now.ToString(); } protected void Timer2_Tick(object sender, EventArgs e) { Literal2.Text = DateTime.Now.ToString(); }
Roughly how often do you think I should expect to see Literal2’s timestamp update? Leave a comment if you know the answer.
Additionally, this code can be “fixed” to yield more intuitive results by adding only one property to one control. What would you do?
Similar posts
What do you think? Your comments are welcomed.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums. If you post there and then contact me with a link to the post, I'll try to take a look at it for you.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this comment" link underneath the comment you're replying to.

Comments
My guess: Literal2’s timestamp is updated every time Literal1’s timestamp is updated. This can be fixed by adding UpdateMode=”Conditional” to both UpdatePanels.
Am I right or not?
You’re right about the UpdateMode, but not about Literal2.
Best practice for multiple update panels on one page is to set all of their UpdateModes to Conditional. =)
Absolutely.
Literal2’s timestamp will never be updated. Timer1 forces an update every 5 seconds on both panels. The update will force Timer2 to reset. Because Timer2 never reaches 10 seconds, it’s event handler is never invoked, and therefore Literal2 is never updated.
That’s exactly right.
Dave,
I’ve seen this in a few places, but I am not exactly sure why it is used. In Case 2, you specify that the interval be 5000 for the timer. Then in the timer event, you set System.Threading.Thread.Sleep to 4000.
What is the significance of System.Threading.Thread.Sleep in this scenario? And, does not using this lead to the potential for an error such as the following error?
“Sys.WebForms.PageRequestManagerTimeoutException: The server request timed out”
Thanks.
Thread.Sleep in code examples is just meant to simulate the delay that would occur when real code was executed (a SQL query, web service call, or whatever). You definitely should never use Thread.Sleep in production code.
Thanks.
Have you seen that error though? I hunting for a reason as to why it happens, and how I can resolve it.
It means that the partial postback took too long to complete (90 seconds, by default).
You can either optimize your server side code to run faster, or use the AsyncPostBackTimeout property of the ScriptManager to increase the timeout (in seconds).
The former is preferable, if at all possible. You typically don’t want partial postbacks to be long running requests, for usability reasons.
Thanks.
Is there no way to disable the timer at the start of the postback, before I used ASP. ajax I was using xml with javascipt and was disableing the settimeout js function before postback, can this be done in this senerio?
e.g
var t=setTimeout(”GetLatestMessages()”,1000);
starts it
then on the sumbit btn I had
if (document.form1.txtMessage.value==”){return false}else{clearTimeout(t);return true;}
I would then start it again with page.registerstartupscript
You can use $find(’Timer1′)._stopTimer() and _startTimer() to control the Timer from the client side.
Personally, I rarely use the Timer. I prefer using setTimeout or setInterval and __doPostBack, similar to the code you posted.