I have a big loop that does a bunch of database processing (loops though a bunch of tables doing stuff).
I would like to update the UI so I know that progress is being made.
What’s a good way to do this in a web app?
I have a big loop that does a bunch of database processing (loops though a bunch of tables doing stuff).
I would like to update the UI so I know that progress is being made.
What’s a good way to do this in a web app?
short answer is that I dont think you can do that. When Ive tried to do something like make a progress bar update in real time or even make a spinner show when a process starts and hide when it finishes nothing goes to the browser until after you finish the current code and return. It just builds up in the buffer and goes all at once when youre done.
The fix is to move your longer processes out to another thread or a series of timer callbacks or something from which you can push updates to the web page. You will have to do the voodoo with the sessionForControl or sessionWithId in order to make your changes go to the watching pages, but it is workable.
James,
I was afraid of that. Since the project is only for internal use, I think I’ll skip it. All the progress messages will appear at the end (or any error messages).
Thanks.
Before you give up, try adding
if i mod n=0 then app.doevents
where i is the loop counter and n is some integer that requests every nth time through the loop (try 10 as a start). The app.doevents is dangerous and many here will jump on my for suggesting it, but under the appropriate circumstances it will work without crashing your program. Since this is an internal program, no harm no foul.
Except never use DoEvents in a desktop app. Ever.
Well, the question was for Web and not desktop. Aren’t Web apps console like? Still, I think that doEvents shouldn’t be used.
The only place you should use DoEvents is a console app since those do not implement an event loop internally. Otherwise, bad.
I don’t think it would help in any event. Since Web sends updates to the browser at the end of an event, you need to be able to break the process into separate events, via a timer or similar.
Confirmed : although doEvents probably would not have the same adverse effects in a web app which, as far as I understand, is a Console program underneath, it will do nothing for the UI.
The only way is to refactor with a thread, and/or a timer.
[quote=386352:@James Sentman]short answer is that I dont think you can do that. When Ive tried to do something like make a progress bar update in real time or even make a spinner show when a process starts and hide when it finishes nothing goes to the browser until after you finish the current code and return. It just builds up in the buffer and goes all at once when youre done.
The fix is to move your longer processes out to another thread or a series of timer callbacks or something from which you can push updates to the web page. You will have to do the voodoo with the sessionForControl or sessionWithId in order to make your changes go to the watching pages, but it is workable.[/quote]
Youre close.
If you use a WebThread for the database work and a WebTimer to request progress updates, you can do this pretty simply.
In the initial trigger, set up and start the WebThread (and make sure it sleeps periodically so it doesnt lock up the other sessions), show the progress indicator and start the WebTimer (mode 2).
In the WebTimer.Action event, check the progress and update the progress indicator. Once the thread is done, whether by finishing or an error, hide the progress bar and set the timers mode to 0.
WebTimers and WebThreads dont need a Session Context.
App.doevents actually will allow a desktop app to update the ui while in a loop. No dont ask me how I know that because youre absolutely never supposed to do that and I always do what Im told except in certain very specific situations where Im stupid enough to think I know exactly what Im doing. Or, when there isnt any other reasonable choice. On the web there is no event loop to return from to have updates. The connection is just waiting for you to finish and then it sends it so I dont believe this will do anything other than make it slower. The solution is to move your work to a thread and either send updates via push or use a web timer to poll for them.
Thanks James for your support.
Thanks for the suggestions.
What I did: Made a desktop app that just did the process I needed. Since I have access to the server (it’s a Mac), I copied the little app to the server, and ran it. It showed progress just fine.
-Bob