Android Question Use Sleep() with variable sleep duration

William Hunter

Active Member
Licensed User
Longtime User
I would like to use Sleep() with a means of varying the sleep duration. I have tried the code below, but get an error. Is there a way to use Sleep, or something similar, with a code set variable controlling the sleep duration? I have been using the Wait Sub below, but a forum search indicates that this is not good practice.

Regards
B4X:
Dim Secs As Int
Secs = ( a variable depending on what is being processed. This is set earlier in code.)

Sleep(Secs * 1000)
B4X:
Sub Wait(Seconds As Int)
    'Sleep for defined seconds
    Dim Ti As Long
    Ti = DateTime.Now + (Seconds * 1000)
    Do While DateTime.Now < Ti
        DoEvents
    Loop
End Sub
 

NJDude

Expert
Licensed User
Longtime User
Sleep takes an integer, you should pass the value of the variable to it, example:
B4X:
Private Secs As Int
Private SetToSleep As Int

'Secs is set somewhere in your code... then you do

SetToSleep = Secs * 1000

Sleep(SetToSleep)
 
Upvote 0

William Hunter

Active Member
Licensed User
Longtime User
Sleep takes an integer, you should pass the value of the variable to it, example:
B4X:
Private Secs As Int
Private SetToSleep As Int

'Secs is set somewhere in your code... then you do

SetToSleep = Secs * 1000

Sleep(SetToSleep)
Thank you NJDude. I had the right idea but left out that extra step. The sub below works as needed.

Regards
B4X:
Wait(1) ' set the duration with the call

Sub Wait(Seconds As Int)
    'Sleep for defined seconds
    Dim SetToSleep As Int
    SetToSleep = (Seconds * 1000)
    Sleep(SetToSleep)
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The above code is incorrect. You should call sleep directly instead of calling a different sub.

In your code the 'wait' sub will be the resumable sub and the calling sub will not wait at all. You can return ResumableSub from wait and then wait for the sub to complete (https://www.b4x.com/android/forum/threads/82670/#content). However it is completely unjustified in this case.
 
Upvote 0

William Hunter

Active Member
Licensed User
Longtime User
The above code is incorrect. You should call sleep directly instead of calling a different sub.

In your code the 'wait' sub will be the resumable sub and the calling sub will not wait at all. You can return ResumableSub from wait and then wait for the sub to complete (https://www.b4x.com/android/forum/threads/82670/#content). However it is completely unjustified in this case.
Thank you Erel. I tried the Sub in a real world setting and you are right, it doesn't work. I tried to do something with ResumableSub, as in the code below. This again does not work. Do you have any thoughts as to how to create a workable Sub using a wait variable? I have a situation where the sleep duration is calculated during other actions.

Regards
B4X:
' Note - Secs is a sleep variable calculated during the execution of previous code.
Wait For(SetToSleep(Secs)) Complete (Result As Object)

Sub SetToSleep(Seconds As Int) As ResumableSub
    Dim Duration As Int
    Duration = (Seconds * 1000)
    Sleep(Duration)
    Return Null
End Sub
 
Last edited:
Upvote 0

William Hunter

Active Member
Licensed User
Longtime User
Just call Sleep(x) directly.

Or Sleep(1000 * x).
Thank you Erel. In this instance calling Sleep directly causes an error. In using Sleep the sub from which it is called becomes a ResumableSub. This interferes with code execution, and I get an error further on.

If I use Sleep(X * 1000) I get this error
B4X:
main_pop_downloadcompleted (java line: 10556)
java.lang.ArrayIndexOutOfBoundsException: length=21; index=21
at mail.purge.whapp.main._pop_downloadcompleted(main.java:10556)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:186)
at anywheresoftware.b4a.BA$2.run(BA.java:360)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
java.lang.ArrayIndexOutOfBoundsException: length=21; index=21
If I use the Wait Sub below all is well, with no error. The only problem being that DoEvents has been depreciated.
B4X:
Sub Wait(Seconds AsInt)
   'Sleep for defined seconds
   Dim Ti AsLong
   Ti = DateTime.Now + (Seconds * 1000)
   DoWhileDateTime.Now < Ti
         DoEvents
   Loop
EndSub
Using Sleep() directly is not always an option, and I would like to have a Wait Sub that doesn’t use DoEvents. If this is not possible I will have to stick with DoEvents for as long as I can, as this is all that works for me.

Regards
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The correct answer is to use Sleep directly. The DoEvents wait loop should be removed if you want your app to work reliably.

I cannot say anything about the other error you get when you use Sleep as you haven't posted the code. If you like to further discuss it then start a new thread with the relevant code.
 
Upvote 0
Top