B4J Question Cascading WAIT FORs

udg

Expert
Licensed User
Longtime User
Hi all,
there's something eluding me when using a few Wait For in order to execute actions one after the other (but only starting an action when previous one is completed).
What happens is that randomly (randomness maybe due to varying execution timing) one of the cascading subs is not executed or it executed twice (well, it returns twice to be more precise)!

The scheme goes like this:

Main
B4X:
Dim rs1 As ResumableSub = cmCommons.SilentSrvSync
Wait For(rs1) Complete (Result As Object)

cmCommons: (used more or less like Starter in B4A)
B4X:
Public Sub SilentSrvSync As ResumableSub
   Wait For(SyncStaff) Complete (Result As Object)
   Wait For(SyncCateg) Complete (Result As Object)
   Wait For(SyncZone) Complete (Result As Object)
   .......
end sub

Sub SyncStaff As ResumableSub
  .....
   Dim pJob As HttpJob
   pJob.Initialize("", Me)
   pJob.PostBytes(wscsync, buffer)
   Wait For (pJob) JobDone(j As HttpJob)
   If j.Success Then
       ......
       Dim rs As ResumableSub = DBData.StaffSrvrUpdt
       Wait For(rs) Complete (Result As Object)
   Else
       Log(j.ErrorMessage)
   End If
   pJob.Release
   Return Null
End Sub

DBData: code module
B4X:
Public Sub StaffSrvrUpdt As ResumableSub
   DBUtils.DropTable(SQL1,"staff")
   SQL1.ExecNonQuery($"CREATE TABLE IF NOT EXISTS staff .....
   .....
   Try
       DBUtils.InsertMaps(SQL1, "staff", ListOfMaps)
   Catch
       Log(LastException)
   End Try
   Return Null
End Sub

DBUtils: version 2.06

My goal is clearly to have a single entry point where a few updates are executed one after the other, strictly in the given order. I could call the single entry point directly from code (as part of the startup process) or later by a button click. Anyway the sequence of actions should be always be predictable.

Can you please spot what is eluding me coding things this way? TIA
 

techknight

Well-Known Member
Licensed User
Longtime User
you cant lockup the main thread.

What I end up doing when I use nested Wait For loops like that, I use AppStart to fire off a timer, and AppStart finishes. its allowed to finish.

Then the timer fires, and picks up execution.

Also every single Wait For (resumablesub) returns a value. and the subroutine that Calls this, is also a resumable sub.

Each sub that calls another sub have to be resumable subs I found out.

I do the same thing, following the above, and it all works perfectly fine.
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Thak you for your reply. So, if I understand it correctly, your advice is to move all the code now in AppStart (including the call to SilentSync) to the tick of a timer.
When the timer ticks, disable the timer, start SilentSync and wait for everything to be over. Eventually timer sub ends, everything is properly set up and Mainform could be showed shaped as needed based on the preceding subs.

Each sub that calls another sub have to be resumable subs I found out.
Agreed. I did the same.
 
Upvote 0
Top