Update Progressbar in Each Loop

Update progressbar in each loop

Okay, I found a solution in the answer to this question:

Javascript: How to update a progress bar in a 'for' loop

var i = 0;
(function loop() {
i++;
if (iterations % i === 100) {
progressbar.set(i); //updates the progressbar, even in loop
}
if (i < iterations) {
setTimeout(loop, 0);
}
})();

My solution:
https://jsfiddle.net/ccvs4rer/3/

Update progress bar in for loop

I found a solution to unblocking the UI by implementing a setTimeout promise like so

const pause = () => {
return new Promise(r => setTimeout(r, 0))
}

and calling it here which gives the UI enough time to update the progress
. I'm pausing the forEach loop few loops to updating the UI and continuing

array.forEach((x, index) => {
store.dispatch({ type: 'PERCENT', payload: percentvalue})
if (index % 20 === 0) { await pause() }
//doing stuff
}

Android - Updating progress bar from for loop in separate thread

AsyncTask is what you are looking for, https://developer.android.com/reference/android/os/AsyncTask.

You would want to place your for loop in the doInBackground method, and you can update your UI in onProgressUpdate. Anything that takes longer than a few milliseconds to execute or blocks your UI, you should do it off of the main thread. This is why you would add your code to the doInBackground method.

onPostExecute runs after your code in doInBackground completes and is executed on the main thread. You can update your UI here.

Here is a really short example based off of your code:

private static class MatchWordsTask extends AsyncTask<String[], Integer, Boolean> {
private WeakReference<ProgressBar> mProgressBar;
private String[] mArray;

MatchWordsTask(ProgressBar progressBar, String[] array) {
mProgressBar = new WeakReference<ProgressBar>(progressBar);
mArray = array;
}

protected Boolean doInBackground(String[]... arrays) {
for (int i = 0; i < mArray.length; i++) {
publishProgress(((i + 1) / mArray.length) * 100);

try {
Thread.sleep(1000);
} catch(Exception e) {
e.printStackTrace();
}
}

return true;
}

protected void onProgressUpdate(Integer... progress) {
mProgressBar.get().setProgress(progress[0]);
}

protected void onPostExecute(Boolean matches) {
Log.d(TAG, "Matches: " + matches);
}
}

You would execute this AsyncTask like this:

String[] array = new String[]{"This", "is", "an", "array", "of", "words"};
new MatchWordsTask(progressBar, array).execute(array);

Update progressbar for each item found

I finally got it ! :)

I tried to use a trick, and it works fine.

I create an integer variable before the foreach, set to 0. Inside the foreach, i increment this variable by one, and send his value to my progressbar as a step.

    private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{

int totalSteps = lv_selection.Items.Count;
int currentStep = 0;

// Installations
foreach (string p in lv_selection.Items)
{
currentStep++;

// My long task

this.Dispatcher.Invoke(() =>
{
progressbarForm.Progress(p);
});

(sender as BackgroundWorker).ReportProgress((int)(100 / totalSteps) * currentStep, null);

}
}

How to change progress bar in loop?

I would do it like that for a dummy progressbar :

Html

<div id="progress">
<span class="progress-text"></span>
<div class="progress-bar"></div>
</div>

Css

#progress {
position:relative;
width:250px;
height:20px;
border:1px solid red;
}

#progress .progress-bar {
background:blue;
height:20px;
width:0%;
display:inline-block;
}

#progress .progress-text {
position:absolute;
z-index:2;
right:0;
}

JQuery

$(document).ready(function() {
var progression = 0,
progress = setInterval(function()
{
$('#progress .progress-text').text(progression + '%');
$('#progress .progress-bar').css({'width':progression+'%'});
if(progression == 100) {
clearInterval(progress);
alert('done');
} else
progression += 10;

}, 1000);
});

jsFiddle

You could use the JQueryUI Progressbar too !

Progress bar won't update from for loop

Seems the Float(i/10) should change to Float(i)/10 because the previous one does the division with two integers then convert to float, it will always return 0 until the i reaches to 10.

Also, if I understand your question correctly, you want to update the progress synchronously with each step i.

Because you are using DispatchQueue.main.async to update the signingBar asynchronously in the main thread, so the for loop will still go on but not blocked by self.signingBar.setProgress.

If you want to make sure the signingBar updates step by step, you can use DispatchGroup to wait until the progress bar updated.

// At each 'i' step

let group = DispatchGroup()
group.enter()

// run function x times
runSignings(iterations: 1)

DispatchQueue.main.async {
// now update UI on main thread
self.signingBar.setProgress(Float(i)/10, animated: true)

group.leave()
}

group.wait()

Hope these above can help you.

Javascript: How to update a progress bar in a 'for' loop

Take a look at the following:

http://jsfiddle.net/6JxQk/

The idea here is to replace your for loop with an asynchronous loop that uses setTimeout(), so you would go from the following:

for (var i = 0; i < rows; i++) {
// do stuff
}

... to this:

var i = 0;
(function doSort() {
// update progress
// do stuff
i++;
if (i < rows) {
setTimeout(doSort, 0);
}
})();

Although as you can see, this significantly slows down your sorting routine because in addition to updating the progress bar, this will reorder the rows of your table. With this in mind I think you are better off just using a built-in sort rather than your own implementation, and dropping the progress bar.

Updating ProgressBar value within a for loop

Background

  1. Platform.runLater() is called to execute something on the JavaFX Application thread when you are on some other thread. You are running it every 100ms when you are already on the JavaFX application thread adding all these items in queue, because the thread is already busy running the loop and sleeping :)

    So it runs everything in queue after the thread is free to execute them i.e. after finishing the loop.

  2. There is another problem, ProgressBar has a progressproperty whose value can be between 0 and 1, where 0 represents 0% and 1 represents 100%. If you want to update the progress bar, you would want to set the progress with values between 0.1 to 1.0.

How to FIX

You should start a new Thread on the button's action and let it handle the loop. You can use Platform.runLater inside this thread, without choking the JavaFX application thread.

I would run something as below :

btn.setOnAction(event -> {
new Thread(() -> {
for(int i = 0; i <=100; i++){
final int position = i;
Platform.runLater(() -> {
pb.setProgress(position/100.0);
System.out.println("Index: " + position);
});
try{
Thread.sleep(100);
}catch(Exception e){ System.err.println(e); }
}
}).start();
});

Note : This answer stresses more on where the OP went wrong and how he can rectify it. If you are on JavaFX, you would want to use better approaches i.e. using Task and its updateProgress() for updating the progress of the ProgressBar as stated by @kleopatra in her solution.



Related Topics



Leave a reply



Submit