How can I report progress based on several variables in a nested loop (for a progress bar)?

I have a BackgroundWorker and one ProgressBar. When running, BackgroundWorker starts through a triple for loop and processes the progress bar.

Currently, the reported progress refers only to the outter-most (xProgress) loop, which works but does not work smoothly. The goal is for the ProgressBar to also take into account the percentage of progress of the inner loops, so that the ProgressBar is updated more smoothly and accurately.

DoWork Method:

private void bgw_DoWork(object sender, DoWorkEventArgs e) { int xMax, yMax, zMax; xMax = 10; for (int x = 1; x <= xMax; x++) { yMax = 5; for (int y = 1; y <= yMax; y++) { zMax = new Random().Next(50, 100); for (int z = 1; z <= zMax; z++) { Thread.Sleep(5); /// The process double xProgress = (double)x / (double)xMax; double yProgress = (double)y / (double)yMax; double zProgress = (double)z / (double)zMax; /// The progress calculation: double progressCalc = xProgress; int progress = (int)(progressCalc * pgb.Maximum); bgw.ReportProgress(progress); } } } } 
+5
source share
4 answers

This works even if you don't know your best / worst case in advance. Any of max can be randomized in the same way zMax .

 static void F() { var r = new Random(); int xMax = 10; int yMax = 5; int zMax; for (int x = 0; x < xMax; x++) { double xProg = (double)x / xMax; for (int y = 0; y < yMax; y++) { double yProg = (double)y / (yMax * xMax); zMax = r.Next(50, 100); for (int z = 0; z < zMax; z++) { double zProg = (double)z / (zMax * yMax * xMax); var prog = xProg + yProg + zProg; Console.WriteLine(prog.ToString("P")); // bgw.ReportProgress((int)(prog * pgb.Maximum)); } } } Console.WriteLine(1.ToString("P")); // Make sure to report the final 100% // bgw.ReportProgress((int)pgb.Maximum); } 

Btw, I would pgb.Maximum with 1 , and in OnProgressHandler I would pgb.Maximum progress on it. Thus, the stream method does not apply to interface elements at all.

+3
source

It’s true that you cannot know exactly how many iterations your loops will perform, but you will probably be able to smooth out the progress indicator.

Suppose your worst case iterations are xMax * yMax * mostZMax.

mostZMax = 99 because the upper bound is exclusive in Random.Next(minValue:int, maxValue:int)

Therefore, the final iterations in the worst case will be 5 * 10 * 99 = 4950 .

Now we could start with this amount and adjust it if necessary, when we lose iterations after generating zMax for each cycle y, and we will smooth out progress and reporting efficiently.

Here's how I do it:

 private void bgw_DoWork(object sender, DoWorkEventArgs e) { const int xMax = 10; const int yMax = 5; const int worstZMax = 99; //because upper is exclusive in Random.Next(lower, upper) var iteration = 0; var total = xMax * yMax * worstZMax; //total number of iterations (worst case) for (var x = 1; x <= xMax; x++) { for (var y = 1; y <= yMax; y++) { var zMax = new Random().Next(50, 100); //get how many iterations did we miss, and adjust the total iterations total -= worstZMax - zMax; for (var z = 1; z <= zMax; z++) { iteration++; //count this iteration Thread.Sleep(5); // The process // The progress calculation var progress = (double)iteration / total * pgb.Maximum; bgw.ReportProgress((int)progress); } } } } 

Hope this helps!

+3
source

Updated answer:

Since the inner loop has an unknown number of iterations, you can decide how many steps it has to complete. e.g. 10.

Then you can do something like this:

 progressbarMaximum = xMax * yMax * 10 

right in front of the z-loop you get zModulo by dividing zMax by 10. in your z-loop check if

 zMax % zModulo == 0 

then increase the progress bar.

Old answer:

If you multiply xMax, yMax and zMax, you get the total number of iterations of the innermost loop.

Set the maximum progress in this value.

At each iteration of the inner increment increment step.

+1
source

You cannot make it accurate. Think of it this way: that if the first random numbers were all 50, and you already made half of the 2 outer loops - if the remaining random numbers are 50, you made 50%. If the remaining random numbers are 100, you will only make 33%. So you don’t know how far the progress bar should be.

(Of course, random results will usually not be that way. It's just to illustrate the point.)

0
source

Source: https://habr.com/ru/post/1261272/


All Articles