udg Expert Licensed User Longtime User Dec 12, 2019 #1 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 Code: Dim rs1 As ResumableSub = cmCommons.SilentSrvSync Wait For(rs1) Complete (Result As Object) cmCommons: (used more or less like Starter in B4A) Code: 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 Code: 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
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 Code: Dim rs1 As ResumableSub = cmCommons.SilentSrvSync Wait For(rs1) Complete (Result As Object) cmCommons: (used more or less like Starter in B4A) Code: 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 Code: 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 Dec 12, 2019 #2 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
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.
udg Expert Licensed User Longtime User Dec 12, 2019 #3 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. Click to expand... Agreed. I did the same. Upvote 0
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. Click to expand... Agreed. I did the same.