Ajax Loader disappears on long running processes

0
0

Hello, some of our screens perform large queries which take over 60 seconds to run (especially in test/development environments.)  The spinny image disappears after roughly 30 seconds, and then the results of the query are not displayed on the screen for another 20 to 30 seconds.  This is confusing for the users because it looks as though the query completed and didn’t return any results.

 

I found this post (https://wisej.com/support/question/please-advice-how-to-show-loader-while-running-long-task-when-i-click-button-for-example) that indicates we need to perform the following steps around long-running processes:

this.Call("showLoader");
Application.Update(this);
// ... long running stuff...
this.Call("hideLoader");

Is this necessary for any and all long-running processes?  This was not necessary in VWG, that's the reason I ask.

Thank you,
Andrew
  • You must to post comments
0
0

Luca, thanks for the sample.  I believe I have found a solution, some very basic testing seems to show it works as we need it to, I’ll post back here if significant changes are needed for future developers.  Changes detailed below:

Default.json
“loaderTimeout”:  50  //Show the loader very quickly, 50ms

Application Main Form changed to implement IEventFilter:

private bool _inExecute = false;
public bool PreFilterEvent(WisejEventArgs e)
{
switch (e.Type)
{
case “interval”: //timer tick
if (this._inExecute)
return true; //don’t fire the timer event if the user is currently doing something. Too many of our controls/timers share resources
break;
case “execute”: //buttonclick
case “selectionChanged”: //selectedIndexChanged event.
this._inExecute = true;
e.Target.Event(e);
this._inExecute = false;
return true;//handled
}

return false;
}

  • You must to post comments
0
0

Got it. The timer control is fired by the client browser, it’s a simple javascript timer. I have seen timers used in VWG to handle updates for long running processes,  it’s not really needed with Wisej. One of the main purposes of a timer is to be able to fire asynchronously.

I understand the need not to change to much from VWG, we are having similar issues on our migration projects, at least for the first stage.

One option would be to register a global application event filter and process button click events and timer events and if the timer event is fired while processing a click event simply don’t dispatch it. I attached a small sample.

In the sample, the timer keeps firing while the process behind the button click is running. Check the checkbox, and the timer events are all discarded while the button (any button) is  processing a click.

There is no performance loss by filtering since that’s where all events are processed anyway.

This sample gives you full global control on how to synchronize events. The sample registers the Page as the filter, but you can use a single global object and register it when the app starts. You can register multiple filters too.

HTH

Best,

Luca

 

  • You must to post comments
0
0

Hi Luca,

One problem I’m having is with timer controls.  If a timer fires while a user request is processing, we are getting occasional errors and unexpected results.  Without getting too deep in the details, if the timer and user request both try to use the same SQL connection, and the user request begins a transaction on that SQL connection, the request made by the timer control blows up and shows an error.

Obviously, we can rework our system to not share resources like that… but it could add a great deal of work to our conversion.  That’s why I asked.

Thanks.

  • redcard
    I can also recreate the issue by quickly selecting different grid view items. The selected index changed event does a database trip on a class-level datatable. By quickly selecting items on the datagridview I can easily blow up the UI. Maybe we can clean up our code to handle this… but it will take a lot more work than we hoped.
  • You must to post comments
0
0

Depends  on the call.

All PerformClick() methods are already protected, if you click a button and the app processes something and while processing you click  the same button again, the click is discarded (not even queued). But while the app is processing something, and the user resizes the window, or resizes the browser, Wisej has to process those calls, otherwise the UI will look frozen.

I guess the issue between two buttons, if the user presses button1, the app is processing something, and while processing the use presses button2, you need the click on button2 not to be processed? Or all click on the parent form, like changing the active tab or selecting another row, should be blocked?

One way would be to disable the container while processing, but it’s probably not a nice thing to disable/enable on each click. We could add a method or property to disable/enable pointer down/up events on the client area of a container without disabling it. Could also make it optionally automatic when clicking a button or a menu item. Would that help?

  • You must to post comments
0
0

Hi Luca, thanks for the response.  I wonder, would it be possible to make each session synchronous, so each user can effectively only gets to execute one call at a time?  If this setting exists we could possibly use it to help simplify our VWG to WiseJ conversion.

Thanks

  • You must to post comments
0
0

Hi Andrew,

The difference is that VWG was processing request/response synchronously while Wisej is fully asyncronous. The automatic ajax loader is shown after a certain timeout (configurable) and it’s removed when a response is received. However, in Wisej there is no one-to-one correlation between a request and a response because there is none when using WebSocket.  When using HTTP we are still asynchronous and a subsequent response may carry all that Wisej needs to update the browser.

Also, a Wisej app can still operate while another request is processing. Basically as soon as there is a successful keep-alive or the user interacts with the app, the automatic loader is removed because of a successful incoming message (WebSocket) or response (HTTP). In fact Wisej tries in many ways NOT to show the automatic loader and in theory it should never show. When it shows it’s because an internal timeout kicked in and it may indicate a problem with the communication or the server not responding in time.

We added the ShowLoader property on the base ControlBase in a previous build to give developers granular control of where and when to show the loader.

You can show it on the entire page and block all controls, or you can show it on specific controls while processing something on the server:

this.ShowLoader = true;

this.button1.ShowLoader = true;

HTH

Best,

Luca

 

  • Luca (ITG)
    Forgot to add that showing the loader on a control masks it and disables all user input to that control (and children).
  • You must to post comments
Showing 6 results
Your Answer

Please first to submit.