Android Question Wait for task to complete

Polaris

Member
Licensed User
Longtime User
I thought i would share my solution for a common problem that developers encounter when the need arises to have the program stop and wait for a task to complete before moving on to the next. It could come in handy to someone.

In these threads :


Erel explains how to wait for a task to complete before moving to the next task.
In my specific case this code could not be applied 'as is' . My app would crash every time . So here is my simple solution, ( not elegant , but works like a charm for me )

Create a Sub ( I call it the waiting sub ) which does nothing but keeps getting called as long as status (0) = "busy" . This keeps the code in a loop until the job is finished and status(0) = " "

My app is a card game where the player choses a hand of five cards form a grid of 20 cards. The cards are clicked or taped on one by one, and once the fifth card is selected the hand is evaluated and rated by the code, and the selected cards are removed from the grid . This only takes a second or two , but if the player were to start selecting a new hand before the eveluation process was done , the selected cards would be regularly highlighted as is expected , but ignored by the code that counts how many cards have been selected, sending the app into a tail spin which would eventually crash it. With the " Sleep comand the app kept crashing , and this solved it for me.





B4X:
Dim status(1) as String       ' Global Array


Sub IV1_MouseClicked(EventData As MouseEvent)

 If status(0) = "" Then                                  '  If status is not busy   ( "")  then the code in the sub is executed  otherwise the code jumps to the end of the Sub.
 
            (All the logic goes here  )
            TotalCards = TotalCards +1
          
              If  TotalCards = 5  Then                  '  By Jumping to the end of the Sub i can keep  the card counter from incrementing  until the EvaluatePokerHand Sub is done
                  EvaluatePokerHand
              End If
Else
         Waitingsub
End if
End sub

   
Sub WaitingSub 
      Do While status(0) = "busy" 
     Sleep (250)                                                 ' Calling sleep  Sleep in this small Sub avoids the probability of causing a crash if I were to call it in a larger more complex Sub
     Log( "Waiting for task to finish") 
     Loop                                                          ' Here the original large Sub can be called again once the loop ends, which in my case is not necessary since it is a MouseClick
End Sub


Sub EvaluatePokerHAnd
         Status(0) = "busy"
 
        ( All logic goes here)

       ( As soon as the hand is evaluated and stored)
      Status(0) = ""
End sub
 
Last edited:

Polaris

Member
Licensed User
Longtime User
Sorry, I'm on holiday , and wrote this post on the fly by the pool without checking anyting. ( It was all wrong )
I edited the code so it should make sense now .
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Since status(0) is already "busy" when you call waiting, the condition in waiting is always true.
Not only that, but it doesn't matter since waiting doesn't do anything.

Maybe when you are back from your holiday, you can test your code thoroughly.
The references to the multiple waits posts are probably not relevant for you.

The following is just an example how it could work without any waits.

B4X:
Dim cardsInHand As Int       ' Global variable

Sub IV1_MouseClicked(EventData As MouseEvent)
    cardsInHand = cardsInHand + 1

    'code to process card

    if cardsInHand = 5 then EvaluatePokerHand
End sub

Sub EvaluatePokerHand
    'all logic goes here
   
    cardsInHand = 0
End sub
 
Last edited:
Upvote 0

Polaris

Member
Licensed User
Longtime User
I had found a working solution for my app and intended to post it in case it could help someone else with a similar problem, but never had the time to sit down and write this post. Then i went on holiday and had plenty of free time, so I thought I would finally write it on the forum, but me writing it from memory was a bad idea, sorry.

Your solution is good but for every card that is clicked you need to store it's value and suit and that has to happen before you can evaluate the hand . Also you need to create some sort of visual effect on the screen for each card selected so the player can see his progress card by card. All this has to happen at every Click or Touch.

Anyways: Yes it's true that status is always busy when I call "WaitingSub", so you're right in saying that it's presence in the code is superflous. But it is so because I call it from a sub that handles a MouseClick event( or OnTouch event). So Yes i could just skip to End Sub if Status(0) = "Busy" and wait for the next Mouse click or screen touch. This way all clicks will be ignored if they happen while Sub EvaluatePokerHand is working, therefore "WaitingSub" is not needed.

However when i was working on the problem using Sleep or Wait For I tried to find a solution that would work for somebody that needs to wait for some task to finish in a Sub that does not handle a MouseClick and if the condition causes the code to jump to End Sub there could be no way to call the sub again once Status(0) goes from "busy" to " "

So having a waiting sub in this case can be a good solution as long as it loops until the status(0) changes from "busy" to "". In fact even the edited post had an error in "Waiting Sub " I had to edit the post once again to get the code right , Sorry again .


So, to recap :

Using a Do While loop with sleep in a complex Sub like Click Event causes it to crash , by moving the loop and sleep into a simple Sub which loops until
Status(0) goes from "busy" to " " everyting goes smoothly. At the end of the WaitingSub the original Sub that required the waiting can be called and this time it will execute normaly . In my case I do not call the original sub because it is a MouseClick Event.

I read a lot of posts where members complain that Wait For comands don't behave as they should, This is probably due to the asynchronous nature of modern OS's, and that's probably why Do While loops in the middle of complex code results in unexpected behavior.
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
This only takes a second or two , but if the player were to start selecting a new hand before the eveluation process was done , the selected cards would be regularly highlighted as is expected , but ignored by the code that counts how many cards have been selected, sending the app into a tail spin which would eventually crash it.
Maybe I am wrong, as I don't know your code or your game, but this doesn't look something for Wait For.
To avoid selecting card when not allowed I would simply use a Boolean check at the beginning of the sub that select/deselect the cards.
Something like this
B4X:
Private Sub ChooseCards
    If evaluating Then Return
    
    'Here goes the cards select/deselect
    If cardsnumber = 5 Then EvaluateHand
End Sub

Private Sub EvaluateHand
    evaluating = True
    
    'Here goes the evaluation process
    
    evaluating = False
End Sub
evaluating is a Boolean declared in Globals and cardsnumber is a Global Int.
Am I missing something important?
 
Upvote 0
Top