Reputation: 555
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
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
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
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