Reputation: 142
In my code, I'm processing a very large number of files and I'm trying to implement a more accurate progress display in my app. Because the files vary so much (1-250MB) in size, and therefore processing time, simply using a counter of files processed doesn't give an accurate representation of the progress.
progress?.Report((i+1) * 100 / total);
Instead, I looked at factoring in the file size with this approach:
progress?.Report(pb.Value + (int)(update.Size * 100 / totalSize));
But, upon completion, the progressbar isn't full which I presume is due to the loss of precision in the division.
My totalSize variable can exceed 2147483647 bytes, so I can't just set the progressbar max value as total size and increment the value by the file size.
Is there an easy way I can accomplish this? The only way I can think of is to just set the progressbar value to be 100% after the final element is done, but I want to avoid doing that if possible. Thanks
Upvotes: 0
Views: 539
Reputation: 30813
There are few things can be improved in your current design to represent better accuracy:
My totalSize variable can exceed 2147483647 bytes, so I can't just set the progressbar max value as total size and increment the value by the file size.
Use long
data type instead of int
. This way, you can store the actual size of your data. The progress bar itself doesn't need to be as accurate as that, but:
progress?.Report(pb.Value + (int)(update.Size * 100 / totalSize)); //note 100
You can actually improve the accuracy of the progress bar by adjusting its progress.Maximum
to be higher (say, progress.Maximum = 1000
then each progress.Value
counts as 0.1% of the total) which will give you 10x more accuracy than the default progress bar settings, provided that your GUI supports such pixel accuracy.
Lastly,
But, upon completion, the progressbar isn't full which I presume is due to the loss of precision in the division.
It could be due to the mentioned reason, or...
It could be due to graphical representation. Since it takes a little delay for the progress bar graphics to be updated. It is possible that you have already finished your process and give right value to progress bar (that is 100/100 or 1000/1000 if you use my answer) but the UI isn't just updated yet. If you want to delay a little bit, simply use Thread.Sleep
.
Also, another possible reason is that the rounding off is messed up somewhere, thus it gives you rounded off value which is a little off like 99/100
. To prevent this, I recommend to process the data using double
instead of integer type before the final representation in progress.Value = N;
assignment takes place. You could also consider using Math.Round
if double
precision still gives you very minor error. The important thing here is good debugging to isolate the cause, then we can apply appropriate fix.
Or it could also be due to the combined reasons above, in which you got to apply both fixes.
Upvotes: 2