One of those ‘doh’ moments

There are times when you feel really proud of yourselves; on top of the world, with no one in sight. And then there are times when you can’t believe you did what you just did. Here’s one of the latter :-


My task was to show a progress bar in our application. Nothing fancy there – just division of the operations to be performed into equal size chunks and Incrementing after completion of each task. Very straightforward indeed.


	int increment;

private void Form_Load(object sender, EventArgs e)
{
int discreteOperationsCount = GetDiscreteOperationsCount();
increment = (int)Math.Ceil((double)progressBar.Maximum / discreteOperationsCount);
}

private void OperationCompleted()
{
progressBar.Increment(increment);
}

It worked great when I tested it with 5, 10, 20 operations. I was even pleased that I cast the numerator to double straightaway, as I was typing code.


Only until I found that the progress bar progresses too fast if the number of operations is more than 100. If the result of the division is less than 1, Math.Ceil pushes it up to 1, which means that the progress bar will be full when 100 (the default Maximum value) operations complete, regardless of the actual number of operations.


Doh.


Ok, I thought, so let’s store increment as a double and call Increment with that number. It would have worked, but for the fact that Increment does not have any overloads – it only accepts an integer. Hmm.. what gives?


After a little bit of thought, I figured out a way – scale everything by the degree of precision needed. With a scaling factor of 10, the calculation now becomes


increment = Math.Ceil((double)progressBar.Maximum / discreteOperationsCount * 10);

If discreteOperationsCount is 520, for example, then increment would become (100 * 10) / 520 * 10 = 19. We still have an integer, but it is more precise than the one calculated earlier.


Of course, you could increase the scaling factor further, and the number of significant digits will also increase exponentially. But the progress bar will have to do some approximation when mapping progress to pixels on the screen, so beyond a point, the increase in precision doesn’t pay off that much.


Like I said at the top of this post, I couldn’t believe I missed testing with the number of operations greater than the progress bar’s Maximum. Truly one of those ‘doh’ moments.

4 thoughts on “One of those ‘doh’ moments”

  1. How about storing the number of completed events in a field? Then, OperationCompleted can avoid bad behavior when the increment becomes less than one.

    private void OperationCompleted()
    {
    completed++;
    progressBar.Value = ((double)completed * progressBar.Maximum) / discreteOperationsCount;
    }

Leave a Reply

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


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>