Graphinder – Reporting progress with Rx.Net

In a last post I’ve shown how we can easily change completely synchronous method yielding from IEnumerable< T > into full fledged asynchronous, notification-driven solution without alternating method at all. Today I’d like to share few more reasons why I was looking for such solution and how adoption of such approach greatly improved responsiveness of my application.

Defining a report

First of all, why I’d ever wanted async notifications?
Well, provided that UX is the case, we would like to actually update user with actual progress we’ve made, wouldn’t we? I guess that would be more than appropriate. Now.. let’s see what could we actually expect from every report?
Since its an algorithm and we expect a solution, we definitely would like to know what’s the CurrentSolution and whether current iteration of algorithm actually provided a new solution to problem, ie. if it was Accepted. Possibly we would like to know what CurrentFitness of solution is, so that we could determine if algorithm is actually improving the solution. Finally, something that would be definitely the case provided that computer time is money – ProcessorTime used up to reach where algorithm is right now.

Of course we would like to be more specific when it comes to actual implementation of algorithm, therefore ISimulatedAnnealingProgressReport could also report on CurrentTemperature, IGeneticAlgorithmProgressReport could report on CurrentGeneration and so on.

Defining point of subscription

Since algorithms will now notify us on every iteration, we’d need to change SearchForSolution() signature, to actually return IEnumerable< IAlgorithmProgressReport > instead of being simple action.
As signature suggests, we’d also need to yield IAlgorithmProgressReport, so that notification of report is actually created.
Finally, we’d need to define point of subscription to progress report notifications.
Let’s expand our IAlgorithm contract by property:

so that anyone can expect now to receive notifications, provided subscription to mentioned property. Now last, but not least: let’s redefine LaunchAlgorithm() implementation in abstract class of Algorithm where we would transform SearchForSolution into IObservable, pass its execution to Scheduler and expose it outside with ProgressReportChanged property.

Example of changes made to Simulated Annealing

While progress report class seems a little too bulky and probably would be better of ending up as so called property bag and there’s a way too wide contract of IAlgorithm for this particular case, I hope you get the idea of what changes were necessary to be made.

Other points of subscription

Currently, there would be probably at least one other point of subscription that would make sense besides IAlgorithm, that is IProblem. Since every algorithm needs to pass chosen solution to problem anyway, it could notify on every accepted solution. We would definitely miss a lot of insight that way tough, as IProblem currently does not know what algorithm works to solve it. That could possibly be easily solved by passing everything over when setting a new solution, but it would also make things ugly up there, while it’s all organized in algorithms’ implementations.
Possibly to report on every solution found (but not necessary accepted), we would also need to pass sort of accepter delegate to problem, so that it would decide on its own, but that’s where it becomes even more messy.

Most changed class of Algorithm can be found here:

And if you want to play around with notifications and their implementations, you can take a look on console playground here:

Leave a Reply

Your email address will not be published. Required fields are marked *