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.