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
Platform.runLater()
is called to execute something on theJavaFX 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.
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
Click Table Row and Get Value of All Cells
How to Start CSS3 Animations at a Specific Spot
Hover Effect Stays After Touch in Jquerymobile
List of All Background Images in Dom
Is There a Limit on Length of the Key (String) in Js Object
How to Make a Pointy Arrow with a Div in CSS
Nav-Collapse Not Working [Twitter Bootstrap]
How to Trigger the :Active Pseudoclass on Keyboard 'Enter' Press? (Using Only CSS)
Using Modernizr and Jquery to Animate If CSS3 Transitions Don't Exist
JavaScript .Replace Alternative
JavaScript - Page Has to Be Refreshed to Show Particle-Slider Logo Effect
Detecting Width: Auto in Jquery
Gulp Less Not Handling Includes Properly, Included Variables Not Defined