[wm21 - android] ExecuteMainThread() very slow

Startbeitrag von ccc2 am 15.12.2016 08:49

Hi,

do not use ExecuteMainThread() in loop as in LooperAddInProgress() example
http://doc.windev.com/en-US/?1000021638&name=LooperAddInProgress

it will be alot faster if you stored the data first in array , then after finish call ExecuteMainThread() and pass array in parameter .

This method will cause extra code but speed different is very big

Antworten:

Hi

Nothing new here: it's the same thing in you fill a looper or table in a loop in the main thread and use multitask to let the UI paint the control each time...

It's a trade off between time needed to load the full control, and time needed to display the beginning of the control and let the user do something with it...

Best regards

von Fabrice Harari - am 15.12.2016 13:05
That what i original though but after some test. i don't think that the cause . I turn off the visibility of looper , enable after data loaded. the test still show that less call ExecuteMainThread() faster.


this is what i found after try and error with multi thread
1. use multi thread only if you want to run more than one process.
2. a process running in multi thread took longer time than a process running in single thread.

for example:

process1 (single thread)
start >-----------10 minutes------------> finish


process1 (multi thread)
start >-----------15 minutes------------> finish



but if you need to run 3 process

(single thread) total 30 minutes
start >-----------Process1 (10m)------------> finish -> start >-----------Process2 (10m)------------> finish -> start >-----------Process3 (10m)------------> finish



(multi thread) total 15 minutes
start >-----------Process1(15)------------> finish
>-----------Process2(15)------------> finish
>-----------Process2(15)------------> finish

von ccc2 - am 16.12.2016 06:51
Hi,

You can also set ThreadPriority, maybe that's why your thread process is slower than the main process ?

Danny

von Danny Lauwers - am 16.12.2016 07:17
I found another weird problem with ExecuteMainThread() . calling many times not only slow down but also cause unstable . app crash more often compare to less call

von ccc2 - am 21.12.2016 12:44
a couple of more you may want to be aware of ExecuteMainThread()

- when passing parameter to ExecuteMainThread() , use local variable make it less crash than not using local variable.

- calling ExecuteMainThread() may trigger exception procedure not found (if calling local procedure).
when windows exit/close the threads can still be active . but local procedure in windows will not exit. because of that ExecuteMainThread() may/ not trigger exception depend whether on windows had finish closing or not.

von ccc2 - am 23.12.2016 04:21
Hi,

Are there any best practice tips or code that we need to execute before calling ExecuteMainThread ?

I have a Android app that is running 24/7, and I had some trouble in getting this application to run stable. These are the changes I have made for refreshing the screen from other threads when info arrives from via Push Notifications or UDP. After these changes the application is stable.

- I have a background screen refresh thread that waits for a thread event that triggers an update of my main window via ExecuteMainThread. There is a wait inside this to make sure that the screen is not refreshed more than 2 times per sec.

Start Gui thread in project code


IF ThreadState("GuiUpdate") = threadUnknown THEN
ThreadExecute("GuiUpdate",threadGlobalContext,Thread_GuiUpdate)
END


Then the thread code itself


PROCEDURE Thread_GuiUpdate()
dbgStandardOutput("## DACareApp Starting Background GUI Thread ##")

LOOP
WHEN EXCEPTION IN
IF (ThreadWaitSignal() = True) AND (NOT gbExitThreads) AND (NOT gbApplicationInBackground) THEN
IF WinStatus(WIN_Main) NotFound THEN
ExecuteMainThread(WIN_Main.UpdateDisplay)
END

// Make sure that the screen is not triggered more that 2 times a second
ThreadPause(50)
END
ThreadPause(25)
DO
// Log error
END

DO WHILE (gbExitThreads=False) AND (gbExitApplication=False)

dbgStandardOutput("## DACareApp Background GUI Thread Stopped##")


If more Signals are triggered when you are already refreshing the screen, it only refreshes the screen once.

To trigger the update I use the following code


PROCEDURE Request_GuiUpdate()
WHEN EXCEPTION IN
// Start the Waiting GUI update thread
IF (NOT gbExitThreads) AND (NOT gbApplicationInBackground) THEN
ThreadSendSignal("GuiUpdate")
END
DO
// log error
END


You can ofcourse set extra parameters to refresh different windows.

With this methode the application is very stable.
When I used a direct call with ExecuteMainThread with every refresh from a thread (Push notification received), the app was unstable. If you don't wait in the gui update thread and call ExecuteMainThread to fast after each other, application becomes more unstable.

I also have tried to use the Wlanguage function RequestUpdateUI from the secondary thread to refresh the screen, but I am unable to get that working correctly. And I also have to use from within a secondary thread:


ExecuteMainThread(WIN_MYWINDOW.DoMyScreenUpdate)


In the function DoMyScreenUpdate, I use RequestUpdateUI() to trigger a background refresh of the screen

But this seems to be so unlogical ???

I would think you could use RequestUpdateUI(Win_Main,) ??

=> Does anybody know how to actualy use RequestUpdateUI, because the help is very fuzzy about this function. I already asked this to support, but I got a fuzzy answer also. Maybe one of the experts on this forum knows the correct usage of this function ?

Even if you use the 'automatic' parameter of a procedure and set it to execute on the mainthread this seems to have the same instability if you call it often. This is probably logical because they will use ExecuteMainThread internally.

There is room for improvement in using the function ExecuteMainThread and for refreshing the GUI from other threads. Especially of called very often !

I hope they have improved this in v22, don't know if anybody has tried this yet ?

If you have more tips on making a WM21 app more stable, please share your tips !

Thanks
Danny

von Danny Lauwers - am 23.12.2016 07:49
Hi Danny,

I confuse this part.

IF WinStatus(WIN_Main) NotFound THEN
ExecuteMainThread(WIN_Main.UpdateDisplay)
END

from what I see, you try to access main thread WinStatus(WIN_Main) while in sub thread

von ccc2 - am 23.12.2016 11:23
Hi,

It is getting the status, to see if the object exists, I do not really access it ? Would this not be allowed in a thread ?

I guess I could always set a global flag when showing the window and closing the window and use that instead of querying the status of the window.

There is no list to see what commands are threadsafe or can be used in a thread or parallel tasks.

Does anybody know if WinStatus(NameOfYourWindow) can be safely called within a thread without problems ?

Thanks
Danny

von Danny Lauwers - am 23.12.2016 11:34
if you need to access anything method/properties related to control / windows must do from main thread unless you are accessing variable .

just create a local procedure

procedure upd_screen()
IF WinStatus(WIN_Main) NotFound THEN WIN_Main.UpdateDisplay


///remove
IF WinStatus(WIN_Main) NotFound THEN
ExecuteMainThread(WIN_Main.UpdateDisplay)
END

///change to
ExecuteMainThread(upd_screen)

von ccc2 - am 23.12.2016 11:47
Hi,

Thanks, that's a better solution. Best to avoid any GUI object.

Danny

von Danny Lauwers - am 23.12.2016 12:40
Hi Danny,


You can totally skip ExecuteMainThread() by using global variable/database


//in thread//

once execute , store the info into global variable/database

///main windows//
set automatic procedure
http://doc.windev.com/en-US/?9000072&name=automatic_procedures&product=WM

which will run and check the global procedure for any update in global variable/database. if no new info don't refresh

this way you don't need to do any thread pause

----- Process Flow -----

main window ------READ----> variable/Database

von ccc2 - am 23.12.2016 16:50
Zur Information:
MySnip.de hat keinen Einfluss auf die Inhalte der Beiträge. Bitte kontaktieren Sie den Administrator des Forums bei Problemen oder Löschforderungen über die Kontaktseite.
Falls die Kontaktaufnahme mit dem Administrator des Forums fehlschlägt, kontaktieren Sie uns bitte über die in unserem Impressum angegebenen Daten.