Progressbar value not accurate?
-
Hi all, I have a strange effect in a little test application which contains a ProgressBar control (set to 'continuous'), together with a list box and a label. All three of them are fed with values from a loop on a different thread (using a delegate) and updated within the same Sub (member of the main form). Just a very simple example from Micrsoft. A funny effect now is that the progressbar seems to be updated with a delay: While the other controls show the value returned from the loop, the progressBar shows an approx. 10% lower value - i.e. when label and listbox show the 50% value, the progressbar stands at 40%, and when the loop is finished (label and listbox 100%) the progressbar still is at 90%. Just to mention it: The code updates the progressbar FIRST with the percentage (with Statusbar.Refresh), and after that updates the other controls. In the application that I plan I didn't want to show the values in labels etc, so the progressbar should show progress more accurate. Compared with the other controls, it also seems to start a little bit delayed... :confused: Are there any known issues with the accuracy of progress bar? Or am I dealing with something like 'race conditions'? Thank you, Mick
-
Hi all, I have a strange effect in a little test application which contains a ProgressBar control (set to 'continuous'), together with a list box and a label. All three of them are fed with values from a loop on a different thread (using a delegate) and updated within the same Sub (member of the main form). Just a very simple example from Micrsoft. A funny effect now is that the progressbar seems to be updated with a delay: While the other controls show the value returned from the loop, the progressBar shows an approx. 10% lower value - i.e. when label and listbox show the 50% value, the progressbar stands at 40%, and when the loop is finished (label and listbox 100%) the progressbar still is at 90%. Just to mention it: The code updates the progressbar FIRST with the percentage (with Statusbar.Refresh), and after that updates the other controls. In the application that I plan I didn't want to show the values in labels etc, so the progressbar should show progress more accurate. Compared with the other controls, it also seems to start a little bit delayed... :confused: Are there any known issues with the accuracy of progress bar? Or am I dealing with something like 'race conditions'? Thank you, Mick
Without seeing your code, it's impossible to tell you what you did wrong.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
Without seeing your code, it's impossible to tell you what you did wrong.
A guide to posting questions on CodeProject[^]
Dave KreskowiakHi Dave, it's basically the code from the Microsoft sample which I had linked to ('Control.Invoke Method'), just with an additional progressbar. But your answer sounds like it's not normal that the control lacks accuracy... The minor changes I made are in the following method:
Public Sub AddListItemMethod() Dim myItem As String Dim max As Integer = 50 Dim i As Integer Dim percent As Integer For i = 1 To max myItem = "MyListItem" + i.ToString() percent = CInt(i / max \* 100) ProgressBar1.Value = percent StatusStrip1.Refresh() myListBox.Items.Add(myItem) myListBox.Update() myLabel.Text = String.Format("{0} entries ({1}%) added.", CStr(i), percent) myLabel.Update() Thread.Sleep(30) Next i End Sub
I also reduced the Sleep time of the thread - that's why I asked if 'race conditions' might be involved. It seems as if the delay between label/listbox and progressBar is getting bigger with a lower value for 'Thread.Sleep' - very little delay with 800, much bigger delay with 20 or 30.
-
Hi Dave, it's basically the code from the Microsoft sample which I had linked to ('Control.Invoke Method'), just with an additional progressbar. But your answer sounds like it's not normal that the control lacks accuracy... The minor changes I made are in the following method:
Public Sub AddListItemMethod() Dim myItem As String Dim max As Integer = 50 Dim i As Integer Dim percent As Integer For i = 1 To max myItem = "MyListItem" + i.ToString() percent = CInt(i / max \* 100) ProgressBar1.Value = percent StatusStrip1.Refresh() myListBox.Items.Add(myItem) myListBox.Update() myLabel.Text = String.Format("{0} entries ({1}%) added.", CStr(i), percent) myLabel.Update() Thread.Sleep(30) Next i End Sub
I also reduced the Sleep time of the thread - that's why I asked if 'race conditions' might be involved. It seems as if the delay between label/listbox and progressBar is getting bigger with a lower value for 'Thread.Sleep' - very little delay with 800, much bigger delay with 20 or 30.
It doesn't work because you're hogging the UI thread with this code. The Thread.Sleep doesn't help. What I mean by "hogging" is that you're not letting the UI thread process any messages from Windows, like WM_PAINT, that tells individual controls to update themselves. For a "quick fix" you can replace the line that says
myLabel.Update()
withApplication.DoEvents()
. This will process all pending messages in the application message pump, including drawing messages. This is NOT the correct way to do this! This is a hack to get your example code working! The correct way to do this would be to move the long running code (you simulated this with the Thread.Sleep call) to a background thread and Invoke calls to update the UI controls on the UI thread.A guide to posting questions on CodeProject[^]
Dave Kreskowiak