I've struggled for the last couple of months to come up with some clean code to report progress to a user. Everything always seems to boil down to:
ReportProgress("Starting Task 1");
doTask1();
ReportProgress("Task 1 is done");
ReportProgress("Starting Task 2");
doTask2();
ReportProgress("Task 2 is done");
//etc... where report progress does some form of output to the user.
The good coder in me screams "There's got to be a cleaner way!" But I'm stumped. Any thoughts?
EDIT :: I'm looking more for information on architectural information as opposed to implementation specific. The code given is very oversimplified.
A fairly simple and clean way would be to create an abstract class that has a
do()
method and abstract doTask() and getName() methods:Then in your tasks:
You could then have a Task that has a doTask() method that runs
do()
on a whole bunch of other tasks. This could easily be recursive, in that any Task might then run a number of sub-Tasks.It depends how much config is needed on the fly, I would expect the code to be very general, and have the tasks be setup via spring or any ioc container.
This would all be in a spring config: The xml config would supply the task object with its name and parameters. then add these tasks to a collection, and hand that collection to the taskrunner.
The task runner is then code that signals the stop and start of each task, but each task then is free to give specific status of how it is going. Also the taskrunner will catch any exceptions and keep going if something errs out. It could be made configurable to say that certain tasks depend on the completion of others, and some tasks should halt everything if they fail.
I disagree that AOP should be used here. overkill.
I wouldn't hand-code the numeric parts of the displayed messages like that (any time you need to add or remove actions or change the sequence you've got a mess of cut-and-paste to do). You'd want whatever object is handling the ReportProgress method to auto-increment itself as it goes along.
Assuming the pattern in what you're doing is:
you can have a "Task" class (parent for all your tasks), whose do() method is subclassed and automatically logs start and end of task.
Just an idea.
In our tool kit, we have a task controller that manages tasks. A task is run as a thread. In addition to typical thread support, a task supports progress methods. One possible view onto the progress is a visual progress bar with a title that refers to task name and step within task. To support visible statistics and status, the code must make occasional calls to the task's progress method. Typically, this is done within for loops since the percentage progress can be estimated by the current index divided by the limit.
The task controller is a useful place to add global thread control, status probes, other statistics and performance measurement hooks. Some multithreaded bugs and timing issues can be analyzed by examining the controller's state, and the state of all the tasks.
You could create a Task class with a name property and delegate. Put each task in a collection, then iterate through it, printing the message and invoking the delegate for each task.