Dialogs and threads - best practice?

Hi all - Just wondering if there’s any consensus or best practice guide for deciding how best to perform an intensive process in web edition (e.g. calculating payroll process for a bunch of staff selected in a webdialog, generating a series of reports to a single PDF in a batch, and so on).

I’ve adopted the practice of pages displaying content only, with dialogs providing all the necessary editing, selection of staff to be paid etc, however when it comes to performing a lengthy task I tried all ways to thread the process from the dialog (can’t - threads don’t work in dialogs, nor do webtimers, settimer etc - these produce illegal cast exceptions because a dialog isn’t a page, and timers run on forever (still) after the dialog has closed, or it crashes).

Example web app here

So, for the time being I just execute the process then release the dialog, which notifies the page that it needs refreshing - but I’m concerned that there may be a hit on performance for other users, even for the few seconds these processes take to run. It’s fine for small numbers of records being processed, but it doesn’t look like it’ll scale well.

I’d prefer not to: release the dialog then run the process in a thread (showing yet another progress dialog then refresh the page when it’s done) - I’m not sure it’s worthwhile doing it that way - never liked threads, messy/evil things.

The same issues present if I was to spawn a console app to do the work - at some point it still needs to inform the user or refresh the page and in the meantime they could go do something else, but payroll is very task-oriented and the job at hand needs doing (as fast as possible with minimal disruption to other users).

I’d prefer to be able to have the process show it’s progress and complete while in the same WebDialog (it just makes sense and looks tidier), but not being able to implement progress etc in the same dialog is frustrating - and messy to close one just to show another.

So, the question is: Is it better to just run the code (easiest), pass the job to a thread handled in the page (displaying another wait/progress dialog), or spawn the task to a console app?

Any (good) advice is much appreciated.

I think that is a question of time :wink:
If that processing takes some seconds, you could do it directly.
If longer (<1min) you could think about a thread. But you have to check that multiple requests are handled etc.
If it takes really long, you should use a worker task. It doesn’t influence the webapp, you have no problem with multiple requests and you could do that on an different machine it needed.

It sounds like you are trying to keep a synchronous hold on an asynchronous world. (I still have vestiges of that in my code)

You don’t have to use threads for such things, a quick response that triggers a timer that calls back and starts your process can give the user UI feedback while your task completes.

But if the task is very long you should probably embrace threads, have them update a property somewhere with their progress and then the aforementioned timer can trigger a simple grab-the-value, pop it into the UI and set another timer for the next update.

As for its effect on other users, the single-core nature of Xojo web might make the console app more attractive. That said, just running multiple instances of your app to spread it across multiple cores may suffice.

As for web dialogs, I’m not too familiar with their limitations but there’s no reason you can’t roll your own. A web container in an existing page with a little creative CSS can look / act like the sort of modal dialog you’re looking for and give you the UI / processing freedom you need.

Because you place treads in the wrong place. Instead of thinking of a dialog as a small window, you got to realize it is no more than an element of the webpage.

Place your threads on the webpage underneath and you will be fine. Same thing for timers. And remember you can use server side timers (the very same as in Desktop) if you experience too many crashes with WebTimers. If needed, use WebSessionContext in action to access Session.
To create a server side timer, drag a generic object onto the webpage and change the super to Timer.

Thank you all for your replies - pretty much along the lines I was thinking.

Yes Marius and Steve, I still think procedurally rather than event(tually) as I expect an app to work the way I want it to, and hold tight to running things in logical order, only to be often baffled by why what seems a simple task made so much more complex by introducing threads.

However, Michel’s comment has made me think of the dialog more in terms of the page it’s being displayed on (session.currentpage) so perhaps I can just trigger a method on the page to instantiate a class (containing thread etc) object on the page to do it’s duty and it will eventually close the dialog when the task has completed (as I avoid timers in dialogs like the plague)…does that sound right?

I’ll definitely give it a go.

That should work just fine. Note that unlike Desktop, you can very well manipulate UI from a thread, so indeed a timer is not necessary to close the dialog.

I fear updating UI (or even calling functions in a page or dialog) from a thread is forbidden by the computer gods :-), so I’ll use a class with a timer and thread and the timer will do the necessary deed (such as updating the dialog’s progress bar, and closing the dialog when the task is complete)

No, no, no. Ask great priest Greg who built Xojo Web : the limitation of accessing UI from a thread does not exist in Xojo Web.

There is such thing as undue complexity. BTW if you use a WebTimer, it IS a UI control, part of the DOM :stuck_out_tongue:

Awesome - I won’t need timers at all then. At last some sense! Many thanks. :slight_smile:
(BTW loving the latest Xojo!)