Showing posts with label independently. Show all posts
Showing posts with label independently. Show all posts

Wednesday, March 28, 2012

Multiple Timers and Multiple UpdatePanels

I am creating a page with many different server controls that each need to automatically refresh independently. I want the developer to be able to specify the refresh time, so I am exposing that as a property of the control. The problem is, whenever the first timer ticks, all the other timers reset (and the label control in each UpdatePanel updates with the current time) even though they are on different intervals. It acts like all the UpdatePanels are posting back, but I know the tick event is only firing on the first timer (the one with the lowest interval). Any ideas as to what's happening here or what I'm doing wrong?

Here is my (raw, not refactored) code (CreateChildControls method):

If AutoUpdateThen Dim panelAs UpdatePanel =New UpdatePanel()Dim progressAs UpdateProgress =New UpdateProgress() _label =New WebControls.Label()Dim timerAs Timer =New System.Web.UI.Timer() panel.ID =Me.ID +"_UpdatePanel" panel.ChildrenAsTriggers =True panel.UpdateMode = UpdatePanelUpdateMode.Conditional timer.ID = panel.ID +"_RefreshTimer"#If DEBUG Then timer.Interval = IIf(RefreshSeconds <> 0, RefreshSeconds, _refreshMinutes)#Else timer.Interval = _refreshMinutes#End If AddHandler timer.Tick,AddressOf OnTimerTick panel.ContentTemplateContainer.Controls.Add(timer) _label.Text =String.Format("Updated at: {0}", DateTime.Now) panel.ContentTemplateContainer.Controls.Add(control) panel.ContentTemplateContainer.Controls.Add(_label) control = panelEnd If
I've also tried creating the timers outside the UpdatePanels and adding an ASyncPostBack trigger on the Tick event of each timer like so:
 
If AutoUpdateThen Dim panelAs UpdatePanel =New UpdatePanel()Dim progressAs UpdateProgress =New UpdateProgress()Dim timerTriggerAs New AsyncPostBackTrigger() _label =New WebControls.Label()Dim timerAs Timer =New System.Web.UI.Timer() panel.ID =Me.ID +"_UpdatePanel" panel.ChildrenAsTriggers =False panel.UpdateMode = UpdatePanelUpdateMode.Conditional timer.ID = panel.ID +"_RefreshTimer"#If DEBUG Then timer.Interval = IIf(RefreshSeconds <> 0, RefreshSeconds, _refreshMinutes)#Else timer.Interval = _refreshMinutes#End If timerTrigger.ControlID = timer.ID timerTrigger.EventName ="Tick" Controls.Add(timer) panel.Triggers.Add(timerTrigger) _label.Text =String.Format("Updated at: {0}", DateTime.Now) panel.ContentTemplateContainer.Controls.Add(control) panel.ContentTemplateContainer.Controls.Add(_label) control = panelEnd If
Thanks! 

D'oh!


A detail I had failed to mention previously was that these update panels are contained within a surrounding update panel. This panel was set to UpdateMode = Always, which was causing all of the UpdatePanels inside of it to automatically update. I set it to conditional and it seems to work fine now.

-Joe

Multiple UpdatePanels = slow (despite UpdateMode=Conditional)

Hi all,

I'd appreciate help with this as it doesn't seem to make any sense.

I have 2 UpdatePanel controls. I want them to update independently so have set the UpdateMode="Conditional". Each control has a listbox and a button, with the button click populating the listbox.

Now, if the listbox in UpdatePanel2 is empty and I click the button to fill the listbox in UpdatePanel1, this update is very quick (it just returns a handful of rows from the database).

Now, let's say I click the button to fill the listbox in UpdatePanel2, and I happen to add a large number of rows to the listbox (say a couple of thousand). This takes about 10 seconds, which is as expected.

But what I wouldn't expect is for this to dramatically slow down any subsequent updates of the listbox in UpdatePanel1. But that is exactly what happens - any update of the UpdatePanel1 listbox now takes about 10 seconds, even for a few rows. It is as if it is filling the listbox in UpdatePanel2 again.

I thought the whole point of having independent UpdatePanel controls with UpdateMode="Conditional" is to avoid issues like this. Of is there some other reason why this is happening?

Many thanks for assisting a frustrated man.

Richard

What's probably happening is that your ViewState is huge after populating the ListBox. After that, any partial (or full) postback will be transferring that entire ViewState back to the server and the server has to go through instantiating the control from that. That's going to really drag down your performance.

If you can run without ViewState on that control (or even the whole page), do so.

More information:http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/


Hi there,

Thanks for the reply.

If this was the case, I'd expect adding enableviewstate=false to both listboxes to fix the problem, but it doesn't make any difference. Just to verify, I checked the viewstate uning javascript after every async postback and it was only a few kbs throughout at most.

Anyone have any other ideas? This behaviour seems to run completely counter to the idea of independent updatepanel controls.

Cheers,

Richard


In fact, try it yourself:

Click "Update Listbox 1" first - it is instantly filled.

Don't forget the reinstantiation on the server side. Theentire Page is instantiated in every postback, not just the portion relevant to the UpdatePanel that's being refreshed. On the server side, you can basically think of a partial postback as a regular postback that takes the rendered HTML and filters it down to just what's relevant to the UpdatePanels being refreshed. However, that selectivity doesn't come into play until the entire page has finished its life cycle.

So, even though you have independent UpdatePanels, most of that independence is an illusion when thinking about performance.


Right, I see (i think). That makes me wonder: what exactly is the point of the UpdateMode=Conditional then?

It has to be said that UpdatePanels are a touch disappointing, since before ASP.NET AJAX came along we used to use XMLHTTP and javascript manually to do this and did achieve the performance benefits in such situations. I think I'll have to go back to using that.

Thanks again for taking time to explain.


UpdateMode Conditional does reduce the amount of data returned over the wire in a given partial postback. It just turns out to be a negligible gain in a situation like yours, where the bottleneck is somewhere else.

What you can do is use a web service or page methods for something like this, while saving UpdatePanels for something like a GridView where you really need the ViewState. The client side framework that we're given with ASP.NET AJAX works great for leveraging light weight services for a more traditional AJAX approach. That just seems to have been overshadowed by the ease of use of the UpdatePanel.