Android Question Wait For in a For Next Loop

Harris

Expert
Licensed User
Longtime User
New to this... Can't seem to nix it.

B4X:
Sub chkmorei
    
    For i = 0 To AllInspects.Size
        
        ChkMoreInspects(i)
' I suspect I need a Wait For here - but what?  Any wait for here will return to the calling sub...
        
    Next
    
End Sub

Sub ChkMoreInspects(i As Int)

    Dim inum As Int
    inum = i 
        Log(" ________________ ChkMoreInspects - "&i)
    If AllInspects.ContainsKey(inum) Then
       If inum = 0 Then
             Log(" Doing Truck: "&DefCM.DefTrkNum)
             CallSubDelayed( Me, "BuildTruckInpection")
       Else
             SetCurrTrlInsp(inum)
               Log(" Doing Trailer: "&DefCM.InspTrl)
             CallSubDelayed( Me, "BuildTrailerInpection")     
        End If
      
    Else
        
        If Inspection.IsPreOnly Then
           PackDefects(1)    ' 1 = pre
        End If
        Inspection.IsPreOnly = False
        Inspection.IsPostOnly = False
'        Exit
    End If
    Wait For CallSubDelayed(Inspection,"Saveit_Complete")  ' The sub is not pausing here "waiting for Saveit completed to be raised")....  

End Sub

Confused as per usual...

Thanks
 

Emme Developer

Well-Known Member
Licensed User
Longtime User
This is the correct way if you want to wait inside the loop
B4X:
Sub ChkMoreInspects(i As Int) As ResumableSub
....
...
Return True
End Sub

B4X:
For i = 0 To AllInspects.Size
wait for (ChkMoreInspects(i)) Complete(result As Boolean)
Next

By the way..

B4X:
 Wait For CallSubDelayed(Inspection,"Saveit_Complete")  ' The sub is not pausing here "waiting for Saveit completed to be raised")....
This doesn't work.
Correct use of wait for is
B4X:
Wait for (Sub) Complete (Result)
If you want to wait for a sub called using CallSubDelayed, you should use CallSub, as CallSubDelayed doesn't return the object. Another way is this:
B4X:
CallSubDelayed(Me,"Subname")
 Wait For Complete

Sub Subname
 CallSubDelayed(Me,"Complete")
End Sub
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Still stuck...

B4X:
Sub chkmorei
' this works.... However, it loops thru because of the Return in ChkMoreInspects
For i = 0 To AllInspects.Size
      wait for (ChkMoreInspects(i)) Complete(result As Boolean)
Next

End Sub

Sub ChkMoreInspects(i As Int) As ResumableSub  ' A problem here...

    Dim inum As Int
    inum = i 'CurrInspNum
        Log(" ________________ ChkMoreInspects - "&i)
    If AllInspects.ContainsKey(inum) Then
       If inum = 0 Then
            Log(" Doing Truck: "&DefCM.DefTrkNum)
            CallSubDelayed( Me, "BuildTruckInpection")  ' this will open a form to do the inspection for a truck  (wait in that sub until saved)
       Else
            SetCurrTrlInsp(inum)
              Log(" Doing Trailer: "&DefCM.InspTrl)
            CallSubDelayed( Me, "BuildTrailerInpection")     ' this will open a form to do the inspection for a trailer
        End If
    Else
        If Inspection.IsPreOnly Then
           PackDefects(1)    ' 1 = pre
        End If
        Inspection.IsPreOnly = False
        Inspection.IsPostOnly = False
    End If

'    CallSubDelayed( Me, "Saveit1")
'    Wait For Complete
' or
'    Wait For (Saveit1) Complete (result As Boolean) ' Called from inspection class when save button is pressed 
'

' None of the above work...  I need to wait here until inspection is complete (in another class sub) before Returning True for next iteration
   
Return True

End Sub

Thanks

Sub Saveit1 As ResumableSub ' ???
   
'    CallSubDelayed(Me,"Complete") '???
   
    Return True
   
End Sub
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Is this proper (Sleep(1000) in a do while loop)? It does produce the desired result - but is it blocking?
I could not get it to behave using Wait For...

B4X:
Sub chkmorei
    Log(" ______________waiting in chkmorei")
    waiting = True
    Dim w As Int
    For i = 0 To AllInspects.Size
        ChkMoreInspects(i)
        Do While waiting
            w = w + 1
            Log("............. waiting by sleep: "&w)
           Sleep(1000)        ' other classes and subs are functional and responsive...    
        Loop
        waiting = True
    Next
    waiting = False
    Log(" ___________leaving waiting in chkmorei")
    
End Sub

Sub ChkMoreInspects(i As Int) '  As ResumableSub

    Dim inum As Int
    inum = i 'CurrInspNum
    If AllInspects.ContainsKey(inum) Then
       If inum = 0 Then
             Log(" Doing Truck: "&DefCM.DefTrkNum)
             CallSubDelayed( Me, "BuildTruckInpection")
       Else
             SetCurrTrlInsp(inum)
               Log(" Doing Trailer: "&DefCM.InspTrl)
             CallSubDelayed( Me, "BuildTrailerInpection")     
        End If
    Else
        If Inspection.IsPreOnly Then
           PackDefects(1)    ' 1 = pre
        End If
        Inspection.IsPreOnly = False
        Inspection.IsPostOnly = False
        waiting = False
    End If

End Sub

Sub Saveit1
    
    Log(" _____Called from Activity Module using - Wait For (CallSub( LogServmod, 'Saveit1')) Complete (result As Boolean)")
    ' This is a service module....
    waiting = False
    
End Sub
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Why are you using CallSubDelayed here?

Make BuildTruckInpection and the other Build sub, subs that return a ResumableSub and wait for them to complete inside ChkMoreInspects.
It is much more complicated than what I have shown... and your simple / easy examples
For example: BuildTruckInpection

B4X:
Sub BuildTruckInpection
 
    Dim lk, inspid, inspidpost As Long
     Inspection.Trk_Trl = 1
    inspid = InspectDB.CheckCurrInspect4Pre( Inspection.Trk_Trl, 1) ' see what type to build (pre/post) -new or existing-(post only)   
    lk = GetInspEqp(1)' 1 truck - 2 trailer - lookup the inspection model
    If inspid = 0 Then 'pre-trip - new once only
       BuildNewInspect(lk, "CMast", "CDet", "WMast", "WDet" )  ' copy the "correct" inspection records from the WMast to CMast (defaults to current)
       Inspection.InspItem = 4
       LogColor(" built new pre-trip inspection",Colors.Green)
    Else   'post trip - look for first time - or copy existing and add to it...
       inspidpost = InspectDB.CheckCurrInspect4Pre(Inspection.Trk_Trl,3)   
       If inspidpost = 0 Then
          ' use pre-trip data for post
          BuildPostTrip(inspid, True)
          ' will build a clean post on next line
      '   InspectDB.BuildNewInspect(lk, "CMast", "CDet", "WMast", "WDet" )
          Inspection.InspItem = 2
          LogColor(" built new post-trip inspection",Colors.Green)
       Else
          BuildPostTrip(inspidpost,False)
          LogColor(" built existing post-trip inspection",Colors.Green)
       End If     
    End If   
 
 End Sub


Then, based on flow...

B4X:
Sub BuildPostTrip(theid As Long, clean As Boolean)

    DefCM.SQL1.AddNonQueryToBatch("DELETE FROM CMast",Null)
    DefCM.SQL1.AddNonQueryToBatch("DELETE FROM CDet",Null)

    DefCM.SQL1.AddNonQueryToBatch("INSERT INTO CMast Select * FROM currimast where TypeID = " & theid,Null)
    DefCM.SQL1.AddNonQueryToBatch("INSERT INTO CDet  Select * FROM curridet where IType =  " & theid,Null)
    If clean Then
       DefCM.SQL1.AddNonQueryToBatch("UPDATE CMast SET INote = ?",Array As String(" "))
    End If
    
    DefCM.SQL1.ExecNonQueryBatch("buildpost")
    LogColor(" Build existing post trip -BuildPostTrip - using pretrip? -"&clean,Colors.Blue)
    
End Sub
 
 
Sub buildpost_NonQueryComplete(Success As Boolean)

  If Success Then
    Log(" Built all tables... now calling inspection")
    CallSubDelayed(Inspection,"btndone_click")  ' just a stub to create the form...
'    Wait For CallSubDelayed(Inspection,"btnidone_Click_Complete")  ' tried this - had no affect...  Probably doesn't go here...
'        Log(" ______________________Waited for btnidone_Click_Complete ")
    
    End If

End Sub

In the end, the inspection form is actually called from the buildpost_NonQueryComplete, using a stub method to open it...
This is where I need to wait - from the for next loop of sub chkmorei... until the Done button is press here... Then do the next inspection (and wait), and the next (if any).
So with all this convolution, I have a difficult time determining where to put what...
I know I tend to complicate matters - but it did work without resumables - however hard to follow and messy it appeared ...
Hence your reason to help us simplify matters with these introductions...

For a trial run, can I (safely) use the sleep as described for the next few days until I get the hang of things (or is she bound to blow up)?
I have many other "fixes" (aside from inspections) that I would like to collect data for while I am on-site and have complete control over the matter...

Thanks
 
Upvote 0
Top