Need help about invokeAndBlock / scheduleBackgroundTask

38 views
Skip to first unread message

Jérémy MARQUER

unread,
Nov 15, 2016, 9:04:10 AM11/15/16
to CodenameOne Discussions
Hi there,

I'm currently implementing a complex application wich required multithreading. I do many access to database to save and read data.

My problem is to have an application with the better UI experience even if I have some hard task to complete, depending on user interaction.

At the beginning, I misundertood why my application was running very jerky on iPad 3 and smoothly on iPad Air 2 : of course the performance of the last one leads us to think there is no problem in code. So I read some informations about EDT and invokeAndBlock method. My idea, as suggested in your post, was to call invokeAndBlock method when I need to do hard task without blocking the UI. 

The issue is I've many "invokeAndBlock" calls which could interfere (with internal calls, for example : showing a dialog), and some code is invoked with an offset (which sometime lead to exception).

What I can't explain is : why sometimes the code inside runnable is executed later ?

I'm trying to use scheduleBackgroundTask instead but it's an async methodology....

(PS : sorry if it's not clear !!)

Thanks ! 

Jérémy.

Steve Hannah

unread,
Nov 15, 2016, 1:09:05 PM11/15/16
to codenameone...@googlegroups.com
One thing you should be aware of when using invokeAndBlock a lot is:

Tasks in the "invokeAndBlock" queue are processed in a First-in-Last-Out fashion (i.e. like a stack, rather than a queue).  So if you call invokeAndBlock(task1), and then you call invokeAndBlock(task2) in a separate dispatch before the first invokeAndBlock call has returned, then the second call will return before the first one.

This isn't a big deal if all of your calls to invokeAndBlock are relatively "fast".  However if you throw a "long-running" task into invokeAndBlock it can cause some undesirable effects.  Modal dialogs in particular use invokeAndBlock to prevent the show() method from returning until the dialog is closed.  This will be a very long-running "task".  So if you have some existing invokeAndBlock calls that haven't yet completed when the Dialog.show() method it called, those calls will also "hang" until the dialog has been closed.

This is likely why your runnable is executed later.

Steve

--
You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codenameone-discussions+unsub...@googlegroups.com.
Visit this group at https://groups.google.com/group/codenameone-discussions.
To view this discussion on the web visit https://groups.google.com/d/msgid/codenameone-discussions/1ae2ec28-7e8c-4a63-bff1-7c91961bae45%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Steve Hannah
Software Developer
Codename One

Jérémy MARQUER

unread,
Nov 16, 2016, 3:55:47 AM11/16/16
to CodenameOne Discussions
Hi Steve,

Thanks for the explanation. I think I've finally found what is the problem. I'm using the library you've implemented (cn1-data-access-lib) which I've modified to save/read object recursively ... The problem is the cost in term of memory when I update/insert an object.


The code which is problematic in the DAO class of your framework is :

/**
* Gets the POJO model object. If it has been GC'd, then this will return null.
*
* @return
*/
T getObject() {
Object o = obj;
if (o != null && (o = Display.getInstance().extractHardRef(o)) != null) {
return (T) o;
}
Log.p("[WARNING] invoking getObject() return null object ! (" + o + ")");
return null;
}

In my case, if a gc occur in the middle of a hard task (save a big object) -> the method "getObject()" return null because of the gc.

Does this mean that I need to perform a gc before each saving of an object ? 
I understand why you are using WeakReference object in the framework but how to manage this in my case ... 

Notice that my problem occur only on iOS/Android and it's random.


On Tuesday, November 15, 2016 at 7:09:05 PM UTC+1, Steve Hannah wrote:
One thing you should be aware of when using invokeAndBlock a lot is:

Tasks in the "invokeAndBlock" queue are processed in a First-in-Last-Out fashion (i.e. like a stack, rather than a queue).  So if you call invokeAndBlock(task1), and then you call invokeAndBlock(task2) in a separate dispatch before the first invokeAndBlock call has returned, then the second call will return before the first one.

This isn't a big deal if all of your calls to invokeAndBlock are relatively "fast".  However if you throw a "long-running" task into invokeAndBlock it can cause some undesirable effects.  Modal dialogs in particular use invokeAndBlock to prevent the show() method from returning until the dialog is closed.  This will be a very long-running "task".  So if you have some existing invokeAndBlock calls that haven't yet completed when the Dialog.show() method it called, those calls will also "hang" until the dialog has been closed.

This is likely why your runnable is executed later.

Steve

On Tue, Nov 15, 2016 at 6:04 AM, Jérémy MARQUER <jrmy...@gmail.com> wrote:
Hi there,

I'm currently implementing a complex application wich required multithreading. I do many access to database to save and read data.

My problem is to have an application with the better UI experience even if I have some hard task to complete, depending on user interaction.

At the beginning, I misundertood why my application was running very jerky on iPad 3 and smoothly on iPad Air 2 : of course the performance of the last one leads us to think there is no problem in code. So I read some informations about EDT and invokeAndBlock method. My idea, as suggested in your post, was to call invokeAndBlock method when I need to do hard task without blocking the UI. 

The issue is I've many "invokeAndBlock" calls which could interfere (with internal calls, for example : showing a dialog), and some code is invoked with an offset (which sometime lead to exception).

What I can't explain is : why sometimes the code inside runnable is executed later ?

I'm trying to use scheduleBackgroundTask instead but it's an async methodology....

(PS : sorry if it's not clear !!)

Thanks ! 

Jérémy.



--

Shai Almog

unread,
Nov 16, 2016, 10:25:07 PM11/16/16
to CodenameOne Discussions
Hi,
the code above seems fine. A GC will clear data and you only see it on the device since the RAM there is more constrained.
The only solution is to save RAM and prevent duplicate loading of data.
Reply all
Reply to author
Forward
0 new messages