Creating a Quick Progress Visual like UpdateProgress

On Thursday, we’re going to go live with our RockPaperAzure coding challenge – and it’s time to brain dump on some of the lessons learned while building out the solution – some small (like this one), some large.

When developing the RPA website, I chose to use ASP.NET Webforms and ASP.NET Ajax.  The reason for this is simple … I’m a big fan ASP.NET MVC, but for this, given the very short time frame, it was the fastest route to completion.   (For those familiar with Aaron’s base project on Github, I thought about doing it all client side via JQuery but wasn’t impressed with the perf, so decided to go server side.)

ASP.NET Ajax has a nifty UpdateProgress control that is useful during async postbacks to show activity, and while it has a display delay property, it doesn’t have a minimum display time property.  This is problematic because if you want a small spinning icon/wait cursor, displaying it too briefly is just an annoyance.  (Of course, brief is good because it means your page is snappy.) 

One of the solutions to this (as I read on StackOverflow) was to simply put a Thread.Sleep in the server postback method, causing the round-trip to take longer and thus display your animation longer.  While this will work, it will crush scalability.  Depending on how many concurrent users you have, a Thread.Sleep on an ASP.NET thread should be avoided at all costs, and this wasn’t something I was willing to do. 

There are a few commercial controls that will do this, and indeed, using the Ajax toolkit, you can develop a control that will accomplish the same.  But I wanted something that I could develop in 5 minutes – basically in less time than it is taking me to write this blog post. 

I already have the spinning icon, so I wrapped it in a div or span (whatever is appropriate):

    1: <span id="ProgressTemplate" style="visibility: hidden;">
    2:     <img src="~/images/rpadie.gif" clientidmode="Static" runat="server" 
    3:     id="imganim" height="18" width="18" />
    4: </span>

Then, we just plug into the request model to show/hide the control.  It’s a little hack-ish – for example, I reset the visibility to visible on EndRequest because the span, with a default of hidden, will disappear on its own.  This can be fixed by making it a server control and enabling viewstate.  Still, not too bad for 5 minutes:

    1: <script language="javascript" type="text/javascript">
    2: <!--
    3:      var prm = Sys.WebForms.PageRequestManager.getInstance();
    4:    
    5:      prm.add_initializeRequest(InitializeRequest);
    6:      prm.add_endRequest(EndRequest);
    7:      var postBackElement;
    8:      function InitializeRequest(sender, args) {        
    9:          postBackElement = args.get_postBackElement();       
   10:          $get('ProgressTemplate').style.visibility = 'visible';         
   11:      }
   12:      function EndRequest(sender, args) {         
   13:          $get('ProgressTemplate').style.visibility = 'visible';
   14:          setTimeout('hideProgress()', 1000);       
   15:      }
   16:  
   17:      function hideProgress() {
   18:          $get('ProgressTemplate').style.visibility = 'hidden';
   19:      }
   20: // -->
   21: </script>

When the Ajax request comes back, it will keep the span visible for 1 second.  Ideally, a nice modification would use a elapsed time mechanism, so if the request actually took 1 second for some reason, it would hide the span without delay.  This isn’t took hard to implement, but broke the 5 minute goal.