New feature: Resumable Subs - simpler asynchronous programming

Erel

B4X founder
Staff member
Licensed User
Longtime User
This is a very early demonstration of a new feature that is coming to B4X:

test.gif


Code (no timers!):

SS-2017-03-28_15.41.54.png


The purpose of this feature is to make it simpler to work with asynchronous methods.
Instead of making a call and then waiting for the result in a different sub you will be able to implement all the logic as if it was non-asynchronous.
B4X:
'pseudo code
Sub Download
  Job.Download(...)
  Wait For JobDone
  If Job.Success Then Log(Job.GetString)
End Sub

This feature is similar to stackless coroutines or async / await in other programming languages.

It is not similar to a loop with DoEvents as the main thread is not caught in the sub. The sub context is stored and is later resumed.
 
Last edited:

narek adonts

Well-Known Member
Licensed User
Longtime User
This is a very early demonstration of a new feature that is coming to B4X:

View attachment 54209

Code (no timers!):

SS-2017-03-28_15.41.54.png


The purpose of this feature is to make it simpler to work with asynchronous methods.
Instead of making a call and then waiting for the result in a different sub you will be able to implement all the logic as if it was non-asynchronous.
B4X:
'pseudo code
Sub Download
  Job.Download(...)
  WaitFor JobDone
  If Job.Success Then Log(Job.GetString)
End Sub

This feature is similar to stackless coroutines or async / await in other programming languages.

It is not similar to a loop with DoEvents as the main thread is not caught in the sub. The sub context is stored and is later resumed.


By my opinion this is a very very very very very important feature !!!! Thank you

When we should see this new feature ?)
 

Beja

Expert
Licensed User
Longtime User
Great improvement for b4j.
Is the sleep function built-in or declared somewhere?
 

ilan

Expert
Licensed User
Longtime User
So those sub will work in the backgroumd?

How do you stop the loop?
Its says while true, while what is true??
 

mindful

Active Member
Licensed User
Can someone tell me what is with that 'refresh' icon at the end of the line when the sub is declared ?
refresh_circle.png
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
btw what are you using to create such small GIF files ?
http://www.cockos.com/licecap/

So those sub will work in the backgroumd?
No. They run on the main thread. However they can be suspended and resumed. In the example above it happens when you call the Sleep keyword.
In most cases it will happen when you wait for an event.

How do you stop the loop?
Its says while true, while what is true??
This is just a simple example. In this case the loops never end. While True means that the loop will never end as the condition is always true (unless you call Exit somewhere).


Can someone tell me what is with that 'refresh' icon at the end of the line when the sub is declared ?
This means that this is a resumable sub. Resumable subs are special. For example you cannot return a value from such subs (once you understand this concept you will see why).

Another pseudo example:
Lets say you need to execute a very large query. If you use SQL.ExecQuery then it will block the main thread and the app will be non-responsive.
With resumable subs you will be able to use the async method as if it is synchronous:
B4X:
Sub Calc
 If SomeCondition Then
   SQL.ExecQueryAsync (...)
   WaitFor SQL_QueryComplete (Success As Boolean, Result As ResultSet)
   'work with result
   'You can access the local variables here
Else
  SQL.ExecQueryAsync (...)
  WaitFor SQL_QueryComplete (Success As Boolean, Result As ResultSet)
  'do something else with the result
End If
'Do something afterwards
End Sub
 

ilan

Expert
Licensed User
Longtime User
Ok i think i understand. The difference between this method and a timer is, the timer has is interval and you can stop it or start it but it should happen outside the timer tick event (i mean to start the timer)

But this method allow me to call again the sub from inside.

So acctually you could do the same with a timer. Sleep(x) would do the same like changing the timer interval. So what am i missing?? Whats the main benefit of this method ??

Thank you
 

stevel05

Expert
Licensed User
Longtime User
Looking at the syntax presumably the Waitfor is instead of a separate callback sub.

Will WaitFor work with existing library callbacks or will they need to be amended?

I am also thinking about callbacks created using JavaObject CreateEvent and CreateEventFromUI.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Ok i think i understand. The difference between this method and a timer is, the timer has is interval and you can stop it or start it but it should happen outside the timer tick event (i mean to start the timer)

But this method allow me to call again the sub from inside.

So acctually you could do the same with a timer. Sleep(x) would do the same like changing the timer interval. So what am i missing?? Whats the main benefit of this method ??
Don't get caught with this simple example. Everything that can be done with resumable subs can also be done without them. However this feature makes many tasks much simpler.
As I wrote the main usage will be with waiting for events.

Another small example that is very simple with resumable subs and more difficult without them:
Moving buttons with 4 animations with different intervals:

test.gif


Complete code:
B4X:
Sub Process_Globals
   Private fx As JFX
   Private MainForm As Form
End Sub

Sub AppStart (Form1 As Form, Args() As String)
   MainForm = Form1
   MainForm.RootPane.LoadLayout("1") 'Load the layout file.
   MainForm.Show
End Sub


Sub b_Action
   Dim b As Button = Sender
   b.SetLayoutAnimated(600, 10, 300, b.Width, b.Height)
   Sleep(600)
   b.SetLayoutAnimated(400, 300, 300, b.Width, b.Height)
   Sleep(400)
   b.SetLayoutAnimated(200, 300, 10, b.Width, b.Height)
   Sleep(200)
   b.SetLayoutAnimated(100, 10, 10, b.Width, b.Height)
End Sub

Try to implement it with timers. You will need to create a class with multiple timers and use a different instance for each of the buttons (you can also use CallSubPlus with 4 subs)
This is again a simple example, think how it will be more complicated to implement without this feature if more logic was required inside the sub.

Will WaitFor work with existing library callbacks or will they need to be amended?
This is a bit too soon to answer as there are many open issues. It will hopefully work with existing events with no changes.
 

LucaMs

Expert
Licensed User
Longtime User
First of all my usual serious question:
Another small example that is very simple with resumable subs and more difficult without them:
Moving buttons with 4 animations with different intervals:
How can you click on those buttons?
:p


Then my less serious question:
What if you use WaitFor and the event will never raise? If you cannot set a timeout I think the project will be locked there.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Last example for today, this time with some logic:

The number of movements is based on the button's text:
3282017.gif


B4X:
Sub b_Action
   Dim b As Button = Sender
   Dim count As Int = b.Text
   b.SetLayoutAnimated(500, b.Left, 300, b.Width, b.Height)
   Sleep(500)
   Dim i As Int = 0
   Do While i < count
     b.Text = i
     b.SetLayoutAnimated(400, b.Left, 200, b.Width, b.Height)
     Sleep(400)
     b.SetLayoutAnimated(400, b.Left, 400, b.Width, b.Height)
     Sleep(400)
     i = i + 1
   Loop
   b.Text = count
   b.SetLayoutAnimated(500, b.Left, 10, b.Width, b.Height)
End Sub
 
Top