Mech_Engineer
Mech_Engineer

Reputation: 555

ProgressBar not visually showing all steps

I made an application that creates 3D models inside Autodesk Inventor. I would like to add a progress bar to show the user how much of the process has finished.

The problem I encounter is that when the process in Autodesk Inventor is consuming a lot of CPU, the progress bar isn't showing all steps and instead jumps (for example 5 steps further) to the end.

Is there a way to force the windows form to show the all the steps? Or is this behavior not common?

Private Sub
    ' Display the ProgressBar control.
    pbBuildProgress.Visible = True
    ' Set Minimum to 1 to represent the first file being copied.
    pbBuildProgress.Minimum = 1
    ' Set Maximum to the total number of files to copy.
    pbBuildProgress.Maximum = BodyComponents.Count
    ' Set the initial value of the ProgressBar.
    pbBuildProgress.Value = 1
    ' Set the Step property to a value of 1 to represent each file being copied.
    pbBuildProgress.Step = 1


    ' Start loop trough all body components
    For i = 0 To BodyComponents.Count - 1

        ' Some code here that does stuff in Autodesk Inventor

        ' Perform a step
        pbBuildProgress.PerformStep()

    Next
End Sub

Upvotes: 0

Views: 1402

Answers (3)

aybe
aybe

Reputation: 16672

A common cause is that the UI thread is called way too often than it can handle.

Simple fix for this is to quantize you percentage progress, below I run an operation that iterates 1 billion times but only sends an UI update every 10 million iterations or 1%.

Code:

var steps = 1000000000;
var step = 1.0d / steps;
var percent = 0;
for (var i = 0; i < steps; i++)
{
    var percent1 = (int) (Math.Floor(i * step * 100));
    if (percent1 > percent)
    {
        // TODO invoke your UI progress bar update here
        Console.WriteLine("Updating: percent = {0}, i = {1}", percent1, i);
        percent = percent1;
    }
}

Result:

Updating: percent = 1, i = 10000000
Updating: percent = 2, i = 20000000
Updating: percent = 3, i = 30000000
Updating: percent = 4, i = 40000000
Updating: percent = 5, i = 50000000
Updating: percent = 6, i = 60000000
Updating: percent = 7, i = 70000000
Updating: percent = 8, i = 80000000
Updating: percent = 9, i = 90000000
Updating: percent = 10, i = 100000000
Updating: percent = 11, i = 110000000
Updating: percent = 12, i = 120000000
Updating: percent = 13, i = 130000000
Updating: percent = 14, i = 140000000
Updating: percent = 15, i = 150000000
Updating: percent = 16, i = 160000000
Updating: percent = 17, i = 170000000
Updating: percent = 18, i = 180000000
Updating: percent = 19, i = 190000000
Updating: percent = 20, i = 200000000

You might also want to run such operation asynchronously:

Task-based Asynchronous Programming

Upvotes: 0

Bugs
Bugs

Reputation: 4489

You should look into using a BackgroundWoker to report progress:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    ProgressBar1.Minimum = 0
    ProgressBar1.Maximum = 10

    BackgroundWorker1.WorkerReportsProgress = True
    BackgroundWorker1.RunWorkerAsync()

End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    For i = 0 To 10

        Debug.Write(i)

        BackgroundWorker1.ReportProgress(i)

    Next

End Sub

Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

    ProgressBar1.Value = e.ProgressPercentage

End Sub

It's not something I ever need to do so if someone with more experience has any input I'll be more than happy to learn a thing or two.

Upvotes: 1

muffi
muffi

Reputation: 364

Try to update your progressbar or form after .PerformStep(). But be aware, it takes a lot of time, especially when your maximum is big. Maybe you could work with a StopWatch and update your form every 250 ms for example.

Upvotes: 0

Related Questions