Progress Bar never moves

I have a process that scans thru a data base recordset

at the start it takes the record count, set the maximum of the progressbar to the record count, and value to 0
it then does a refresh (and I’ve tried invalidate as well)

as it loops thru the record set
each time it passes a 5% mark (5% of the total, 10%, etc.) it updates the progress bar value, and does a refresh on it
so the progress bar value gets updated 20 times.

HOWEVER… the progress bar stays at the DEFAULT value (50 of 100)

And yes, I have put breakpoints, and I have examined all the values…
It is almost as if everything is working, EXCEPT it never updates the display of the control

OSX… El Capitan… XOJO 2015r2

Try with a Label instead and update the text accordingly. Just to be sure it does count correctly.
Or add system.debug with the count value and see if it indeed counts correctly.

If the loop is inside one event, then you need App.DoEvents for the UI to update while the event is not over.

The alternative is to do your database scanning inside a timer.

[quote=221632:@Christoph De Vocht]Try with a Label instead and update the text accordingly. Just to be sure it does count correctly.
Or add system.debug with the count value and see if it indeed counts correctly.[/quote]
A label defeats the purpose of the progress bar, as as I indicated above… it is infact counting correctly

[quote=221633:@Michel Bujardet]If the loop is inside one event, then you need App.DoEvents for the UI to update while the event is not over.

The alternative is to do your database scanning inside a timer.[/quote]

BUT… app.doevents is EVIL!!! (lol)
besides isn’t the supposed to be the net effect of “REFRESH”…
and I want the movement of the recordset to drive the progress bar, not a timer driving the recordset, which is why I only have it update every 5% instead of every increment (sometimes the total is 10,000, so it would update every 2000 records not every single)

but app.doevents did seem to do the trick

[quote=221639:@Dave S]BUT… app.doevents is EVIL!!! (lol)
besides isn’t the supposed to be the net effect of “REFRESH”…
and I want the movement of the recordset to drive the progress bar, not a timer driving the recordset, which is why I only have it update every 5% instead of every increment (sometimes the total is 10,000, so it would update every 2000 records not every single)[/quote]

Until an event ends, the UI will not be updated. So you can do as many refresh or invalidate as you want, they will not take effect until the end of the event.

I know I will be excommunicated for telling, but App.DoEvents is the only way to have the UI updated while an event is not over. That is exactly what it is supposed to do (hence its name BTW).

The properly sanctified way is to put your unmodified code in a thread, then have it update a property, which a timer picks at regular intervals to apply to the ProgressBar.

C’mon Michel. Time and time again the Xojo engineers post on this forum for such an instance "Use a thread, Do NOT use App.doEvents for this situation.

That is what I understand to be the correct way as well, directly countering your previous statement that [quote] App.DoEvents is the only way to have the UI updated while an event is not over.[/quote]

[quote=221684:@Roger Clary]The properly sanctified way is to put your unmodified code in a thread, then have it update a property, which a timer picks at regular intervals to apply to the ProgressBar.
That is what I understand to be the correct way as well, directly countering your previous statement that

App.DoEvents is the only way to have the UI updated while an event is not over.[/quote]

Roger, I hope you picked up the joke.

Fact remains, as far as I know DoEvents is the only way in pure Xojo (discount eventual declares) to update the UI while an event has not finished. An ongoing event even stops execution of timers.

The Thread Run executes separately, and precisely has nothing to do with the UI. It has nothing to do with the main thread.

Maybe I should have written more precisely :
App.DoEvents is the only way to have the UI updated while an event in the main thread is not over.

Michel, apparently I missed the joke :slight_smile:
When Norman, Joe, Greg, (previously) Thomas, et al tell me via this Forum to not use app.doevents in a GUI app, I don’t use it.

[quote]Fact remains, as far as I know DoEvents is the only way in pure Xojo (discount eventual declares) to update the UI while an event has not finished.[/quote]What is not “pure Xojo” about a separate thread?

[quote=221690:@Roger Clary]Michel, apparently I missed the joke :slight_smile:
When Norman, Joe, Greg, (previously) Thomas, et al tell me via this Forum to not use app.doevents in a GUI app, I don’t use it.
What is not “pure Xojo” about a separate thread?[/quote]

Indeed you should not use App.DoEvents in a Desktop app.

A separate thread is indeed pure Xojo. Declares are not.

Just to be more precise, a UI CAN update itself before an “event” - call it a routine, or a chain of routines, etc. - completes. It is not true that the “event” HAS to finish.

The most precise way of saying it is that you cannot predict with any certainty the operating system’s scheduler.

Instead of complaining about the problem, the solution really is to design widgets and code from the outset where as many routines as possible run in threads. Personally, I wish Xojo was not designed so strictly in this way. Setting a ProgressBar’s value and calling Refresh SHOULD refresh it immediately, like any inline function would. To me, it’s the biggest limitation of Xojo period. It strongly influences a more complicated design, whereas instead the earlier suggestion would be so much easier.

[quote=221694:@Garth Hjelte]Just to be more precise, a UI CAN update itself before an “event” - call it a routine, or a chain of routines, etc. - completes. It is not true that the “event” HAS to finish.

The most precise way of saying it is that you cannot predict with any certainty the operating system’s scheduler.[/quote]

It’s worse than that. Put a tight loop in a button Action event and the whole app execution shuts down while the event has not finished. And that includes timers. Only threads continue to run. So indeed the scheduler goes on, but the UI definitely does not update for as long as Action lasts. On top of it Cocoa will blast the beachball, and Windows will complain that the app has stopped working.

I disagree about that being a bad design, though. Xojo is event oriented. Any long running operation should be placed in a thread, and such things as ProgressBar should be driven by short events happening in timers. Heck, even scanning a database can be done in a timer, instead of in a procedural way.

I am coming from an era when procedural programming was the only thing available. Sorry to say it this way, but it is not simpler, especially if you want to design a responsive UI. Event driven is far superior.

If you use Refresh on a control after you change it’s value, it often DOES update, in my experience. With the latest Xojo maybe it’s different so I could be wrong there. But not in my vast experience.

You said “any long running operation” but the OP didn’t say he was running anything “long”. Plus, sometimes a function will be lengthy, sometimes it won’t - it can depend. I didn’t write REAL/Xojo, but if I did, I would consider Refresh() simply an inline function on the main thread. Call Refresh, the UI updates before Refresh() returns. Duh. That’s common sense in anyone’s book. But REAL/Xojo doesn’t exactly work that way, and I’ve come to live with it. But, “now that you mention it”…

But, my correction is correct. It’s NOT a hard and fast rule that a “event” (whatever you call it, you didn’t define it) has to conclude until the UI updates. The UI isn’t ALWAYS last in the food chain. It’s ALL UP to the scheduler, and it may be in different moods at different times.

Regarding App.DoEvents, all “in the know” understand it’s necessary sometimes. We live and work underground and in hiding about this, and though we agree on The Rule, we have long-standing wisdom and understanding of Reality. If you try to accuse us, we’ll deny it every time. Luckily you can’t see our code. ha ha ha…

The need for a ProgressBar usually does not rise for an operation that takes less than a second…

I would love for the scheduler to be that versatile. In all the tests I have conducted, the UI is frozen until an event handler concludes. Maybe not a method, I have not checked. You see, I cannot rely on a whimsical scheduler. Call me paranoid, I do not trust luck in matters of programming.

As for DoEvents, I was never able to evidence the reentry phenomenon warned against time and again. I would love to, though. It is better to verify experimentally than be afraid of an elusive boogy man.

Not sure if this can be of any help…

I’ve noticed a weird behavior after upgrading to El Capitan. Basically some windows with a progress bar that used to show and refresh properly now seems frozen. This can be easily seen on the Xojo splash screen during Xojo startup: the progress bar doesn’t show anymore.

[quote=221810:@Massimo Valle]Not sure if this can be of any help…

I’ve noticed a weird behavior after upgrading to El Capitan. Basically some windows with a progress bar that used to show and refresh properly now seems frozen. This can be easily seen on the Xojo splash screen during Xojo startup: the progress bar doesn’t show anymore.[/quote]

This may be what my issue is… as the techniques I am using are ones I have used in XOJO for years before upgrading to ElCap

It may be like the Thread Accessing UI Exception, and it is possible El Capitan is stricter when it comes to what is allowed in an event in terms of accessing the UI. But the issue is not recent :

August 2014 https://forum.xojo.com/14805-progressbar-containercontrol-and-threads/0
April 2015 https://forum.xojo.com/21317-refresh-screen-during-a-loop/0

In this June thread, Thom McGrath notes that Refresh can work but strongly discourages it :
https://forum.xojo.com/23236-desktop-to-web/0

[quote=193788:@Thom McGrath]@Michel Bujardet the UI refreshes only when events are over, which means ProgressBar and other things of the same nature must be run by timers[Referring to Web].
To be nitpicky, this is 100% true of desktop code as well. The only difference is that Refresh exists on desktop to force an update synchronously. But I recommend that like I recommend walking on hot coals.[/quote]

It really seems like the Thread+Timer technique is the safest today.

It was my understanding that

REFRESH - do it NOW (akin to app.doevents)
INVALIDATE - do it as soon as you can (ie. and next event threshold)

[quote=221873:@Dave S]REFRESH - do it NOW (akin to app.doevents)
INVALIDATE - do it as soon as you can (ie. and next event threshold)[/quote]

That is correct.

Except that is not what is happening… it requires REFRESH AND doEvents

This is a change recently, since before this worked

for i=1 to someValue
   ..... do some work
  progressBar1.value=progressBar1.Value+1
  progressBar1.refresh
next i

Correction : in practice it WAS correct up until mid 2014 (see posted links). A quick experiment showed Refresh not to work that way.

It seems that Cocoa, possibly Yosemite and El Capitan tightened the rules.

I wanted to make sure, so I loaded a test program in RS 2012R1.2. With Carbon, the bar progresses just fine, and a Label content updates nicely. With Cocoa, the progressbar does not budge until the end of the event, while a label content updates. Sames thing as 2015R2.4.

Incidentally, Xojo Web has the same rule : no UI update until the end of an event.