YOUR FEEDBACK
Gregor Rosenauer wrote: well, not what's your take on this? Did I miss a second page of this article or...
AJAXWorld RIA Conference
Early Bird Savings Expire Friday Register Today and SAVE !..


2008 East
DIAMOND SPONSOR:
Data Direct
Frontiers in Data Access: The Coming Wave in Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
Intel
Virtualization – Path to Predictive Enterprise
Green Hills
IT Security in a Hostile World
JBoss / freedom oss
Practical SOA Approach
GOLD SPONSORS:
Software AG
The Art & Science of SOA: How Governance Enables Adoption
PlateSpin
Effective Planning for Virtual Infrastructure Growth
Fujitsu
Automated Business Process Discovery & Virtualization Service
Ceedo
Workspace Virtualization
Click For 2007 West
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
SYS-CON.TV
POWERBUILDER LINKS YOU MUST CLICK ON


User Interface Design for Long Running Processes
User Interface Design for Long Running Processes

Almost every application has one or more long-running processes. Typically these are things like importing, export and reporting. Waiting for the processes to complete can be tedious for your users. There are techniques you can use to make this less painful. When designing a long running process, there are two concepts to keep in mind. First, your user interface should always be active and responsive. In other words, the user interface should always re-draw itself. Second, you should endeavor to show the progress to the user as your process executes. Keep the user updated and he'll be more patient. However, writing your code to do these two things well can be rather tricky. This article will illustrate common ways to do both.

When designing a long running process, there are two concepts to keep in mind. First, the user interface should always be active and responsive, that is, it should always redraw itself. Second, you should endeavor to show the progress to the user as your process executes. Keep users updated and they'll be more patient. However, writing code to do these two things well can be rather tricky. This article will illustrate common ways to do both.

Yielding to the GUI
Have you ever run an application and initiated a process only to see the cursor change to an hourglass and the application lock up until the process is over? Then, when you move another window on and subsequently off the application's main window, the application doesn't repaint itself?

These are symptoms of an unresponsive user interface. All of the application's CPU time is devoted to running the process, with no time available for updating the user interface. If you code your process without any consideration of the user interface, your application will behave like this. How do you prevent it? You need to allow your application a little time to repaint itself. To do this use the Yield function. Sprinkle your process with calls to Yield. Each time Yield is called, your process will pause for a split second and allow your application's window to repaint itself. Make sure your process calls Yield every few seconds, if not more often. What I just described is the most common technique used by PowerBuilder programmers to allow a responsive user interface during a process. This is the easiest methodology but not necessarily the best.

Multithreading Using Shared Objects
What's the best technique? It's multithreading. PowerBuilder allows you to write multithreaded applications using shared objects, which are regular PowerBuilder nonvisual objects that have been registered using the RegisterShared Object function. Once you've registered your nvo as a shared object, just get an instance (SharedObjectGet) and execute the function that starts your process.

To use shared objects you'll need to encapsulate your process within a nonvisual object. Furthermore, that nvo mustn't refer to any global variables, windows or any other instantiated objects normally available - the process must be self-sufficient. If it needs other objects, it must instantiate them itself. This is necessary because shared objects run in their own session and thus their own thread. While this is more complex than the previous technique, it does offer us many benefits. Our main application session is completely unaffected by the process: the user interface is responsive and alert, and users can even continue to perform other work while our process continues executing in the other thread. As we get into progress displays and status dialogs, you'll see even more benefits to this technique.

Progress Displays - Progress Meter
We know how to keep our interface active and alert, but our users really want more. They want something to tell them how much longer the process will take, some sort of status display. The most common way to do this is with a progress meter (see Figure 1). In PowerBuilder 7 we have two new progress meter controls - horizontal and vertical. To use a progress meter just stick it on your window, then update it throughout the process. Probably the most difficult part about using a progress meter is knowing when to update it. If your process is relatively simple - let's say you're looping through 100,000 rows of data and writing them out to a file - it might not be that difficult. In this case you can set the progress meter's max position to 100 and increment the meter by 1% every time you process a thousand rows. If your process is more complex, you must become creative. Maybe your process does more than one thing. Let's say it retrieves some data, manipulates it, then writes it back to the database. In this situation you should guesstimate what percentage of time each part of the process will take up. Maybe the retrieval will take 40%, the data manipulation 20% and the update back to the database the remaining 40%. Now you could just update the meter three times: when the retrieval is complete, update the meter to 40%; when the data manipulation is complete, update the meter to 60%; when the database update is complete, update the meter to 100%. This display will satisfy most users, but just for fun I suggest throwing in an animated GIF above the progress meter. Users will forget how long it's taking for your process to complete when their attention is diverted by the spinning globe or flying papers.

Progress Displays - Step Display
Sometimes your process won't lend itself to a progress meter. Perhaps you can't estimate the percentage of time each part of your process will take, or maybe your process has a variable number of parts. In these situations I suggest using a kind of step display (see Figure 2). Instead of updating a meter, display the part of the process that's currently executing. Users may prefer the precision of a progress meter, but when that technique isn't practical, a step display is preferable to leaving users in the dark.

Combining Techniques: The Best of Both
You may decide to use shared objects to make your application multithreaded, or a progress meter or step display to show progress. But how do you combine the two? There are two methods:

  1. Open a new window from your shared object and use it to display the progress bar or step display.
  2. Include the progress bar or step display in the main session, perhaps on the main window or a nonmodal popup window.
If you choose the first option, you suffer the same problems in the shared object session that you suffered before you used the shared object. That is, the window that was opened from your shared object session won't get any CPU time to repaint itself, so at least part of your user interface is unresponsive. If you use the latter option, you don't suffer this problem but do add some complexity. You must pass information about our process's progress from the shared object session back into the main session. While this option may be more complex, it's the least problematic.

In order to accomplish this messaging between sessions, you need to create an nvo just for messaging. This nvo should have at least one function that, when called, will update the progress display in the main session. Instantiate the object within the main session and pass a reference to it into the shared object session. The shared object then calls the function on this object, which updates the progress display. If you're using a progress meter, your shared object may need to call this function every time the progress meter needs to be incremented. If you're using a step display, your shared object may need to call this function every time a step is complete and a new step is started.

If you wish to take this object to the next level, you can add one more function that can open your progress window and start your progress. Now this messaging object has become more like a full-blown service object. Even though these techniques, such as the progress display in the main session and developing a progress messaging/service object, require more effort, you'll encounter fewer problems and your code will be more robust.

Note on Animated GIFs
If you follow the earlier suggestion to use an animated GIF, you'll benefit more from executing your process through a shared object. PowerBuilder requires CPU time to redraw the GIF as it animates. If the animated GIF and the process are located within the same session, PowerBuilder won't have enough CPU time to draw the animated GIF smoothly. This will result in choppy animation at best. However, if the animated GIF is located in your main session while the process runs in the shared object session, PowerBuilder will have enough CPU time to draw the GIF and the animation will be smooth.

Adding a Cancel Button
You've almost got it all. Your process is running as a shared object and a progress meter to boot. But users are asking for one more thing - a cancel button. Given our design, it's not that difficult to add. First you need to add a property (instance variable) to the messaging nvo. This should be a boolean variable, false by default and true should the process be canceled. The cancel button, which should exist within your main session alongside your progress meter, will alter this property to true when clicked. Finally, our process needs to check periodically with the messaging nvo. If it finds that the nvo's cancel property is true, it performs whatever actions are necessary to cancel the process. Most likely you'll want to check this property just before or after you update your progress display. By adding the cancel button, you've given the users a feeling of control over the process.

Conclusion
As you can see, with a little forethought you can create alert and communicative interfaces for your long-running processes. Whether they're imports, exports or other similar long-running processes, you have the ability to incorporate several techniques that will make your users more content. Progress meters, animations and cancel buttons will all increase the level of comfort your users enjoy while running your applications. Implementing these features can be tricky, so when you're ready to code, refer to the step-by-step guide in Table 1. It may also be helpful to download the sample code for this article from my Web site ( www.geocities.com/~cgross1). If you have any questions or comments, please send me an e-mail.

About Chris Gross
Chris Gross is a software development manager for Chesapeake System Solutions in Owings Mills, Maryland.

PBDJ LATEST STORIES . . .
Join Scott Guthrie as he discusses Microsoft’s commitment to web standards development, Rich Internet Applications and how Microsoft is contributing to help move the web forward. Join Adobe’s Kevin Lynch as he demonstrates how Flash and HTML come together to make the most engaging,...
Particularly in a means of moving PowerBuilder applications to the web. What I’m looking for doesn’t require a server license or the installation of unmanaged code to the web server, and works well across different browsers (not just Internet Explorer). The WPF DataWindow will help...
"The rise of Enterprise Architecture is proof that organizations need to manage the impact of changes in competition, technology and regulations across their enterprise," said Dan Lahl, director of Intelligent Enterprise for Sybase. "PowerDesigner 15's unique Link and Synch technology ...
With PowerBuilder 11 Sybase gave developers what we have long hoped for – the possibility of taking an application created in a client/server architecture and turning it into a Web application, almost without having to move the code; and it's better if you don't use a server applicat...
Like any standard .NET application, the PowerBuilder .NET application follows the common language runtime rules regarding the permissions needed to do the operation the application aims to do. The code access security (CAS) provided by the .NET Framework is a security mechanism that a ...
PowerBuilder 11.0 supports deploying existing PowerBuilder client/server business applications as an ASP.NET WebForm application. This greatly improves developer productivity without having to learn a new development language and preserves PowerBuilder development skills. Although the ...
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON FEATURED WHITEPAPERS

ADS BY GOOGLE
BREAKING POWERBUILDER / SYBASE NEWS

Sybase 365, a subsidiary of Sybase, Inc. (NYSE:SY), the global leader in mobile mes...