views:

70

answers:

4

When performing a long operation in your application, how do you promote information from your business tier to your UI?

Events? Passing in a status object which is hooked to the UI?

Before I start I just wondered what cunning ways you guys and girls have come up with.

A: 

You should make a difference between: this can be done in a GUI-app and this needs to be done in batch.

Something that runs for 5 minutes: in your gui-app or in batch?

Natrium
This would be an application with a GUI and a buisness layer doing the work
Anthony Johnston
ok, very good. But what I'm trying to say is: if you think the process is running for too long, it's perhaps better to do all the work in batch.
Natrium
thanks but no, this is a question about providing feeback to a user specifically not using a batch
Anthony Johnston
A: 

If we consider a typical Web app - one that is not using a push technology such as COMET, updated information will be fetched by the browser intermittely, perhaps when the user requests, perhaps when an AJAX background call is made.

In that scenario I have my service offering a Status operation.

 int requestSomeWork( ... data ... ) ; // returns an id

 Status getStatus( int id );  // tell me about a previously submitted request

This style is useful not only for displaying progress information but also in recovery from failure scenarios. I may provide additional methods so that we can determine what happened if the Browser or Server crashes just as we were creating a request

 int[] findRequest( ... search Criteria ... );  // I think I submitted a request like ... what's its id?

If we have a "live" UI, either thick client or COMET then we can add event processing

 void registerForUpdates( id, callMe );
djna
A: 

This seems exactly what events are designed for. Letting other objects know about changes to that object.

Having an ProgressUpdated event that reports a progress percentage or something along lines is how I would do it.

Alastair Pitts
ok, so how about passing an object which raises events through methods, like IncrementStatus(). That way you can have one object which you can use again for different operations on different objects and have the UI hook up to it?
Anthony Johnston
+1  A: 

There are two ways I usually do this:

  1. Pushing data with events. Quite simply, the long method knows how much it's done and whenever it finishes a piece it raises an event and pushes data to the UI.
  2. Polling. Suppose the method is for reading a file. It will always update a property somewhere with its progress, and the UI will poll that property once every 100-200ms to update the progress. The reason for 100-200ms is that lower than that the user won't notice and it will only slow down the operation; higher and the progress would be 'clunky'.
configurator
I find polling very effective too. Events work fine, mostly, but they *do* slow down running code if you must synchronize threads, so use events sparingly, only in outer/bigger loops.
Wez
Polling is good only in cases when events would fire too fast, I think. Note that events don't have to slow down code because they can be raised in their own thread, and if going to the UI should use BeginInvoke and not Invoke()
configurator