Android Question the time setting for Sleep statement seems not working

Hi all, I have a question regarding the sleep(milliseconds as int) statement.
According to the official tutorial, the sleep statement suspends the execution of the current subroutine and resumes it after a specified time. However, in the following demo, I found that the specified time doesn't seem to work.
I am posting B4J code, but the same is true for B4A.

demo:
AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show

    Log("app start")
    test
    beginTime=DateTime.Now
    Log("beginTime: " & beginTime)
    Log(count)
    
    'count will increase from 1 to 121
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    ...  ‘ I omitted most code here for simplification

    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    Log(count)
    count=count+1
    endTime=DateTime.Now
    Log("endedTime " & endTime)
    Log("duration:  " & (endTime-beginTime))
    Log("max(count)=" & count)
End Sub

Private Sub test
    Log("welcome to test")
    Sleep(1)
    Log("test ended")
End Sub


The output is like this:
output:
Waiting for debugger to connect...
Program started.
app start
welcome to test
beginTime: 1711369282467
1
2
3
4
...'  I omitted most output lines here for simplification'
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
endedTime 1711369282485
duration:  18
max(count)=121
test ended

It seems that the test subroutine is continued after all the rest codes in the appStart routine have been executed which costs 18 milliseconds.
I am wondering if this is something wrong? Or is it a feature of b4x?
 
The Sleep call in "test" sub has no effect on the calling sub.

If you want to call a resumable sub and wait for it to complete: [B4X] Resumable subs that return values (ResumableSub)
Sorry, I am not quite getting it. Do you mean, with sleep statement, the calling sub and the test sub behave like 2 independent "machines" with different "timelines"? The calling sub "machine" continues from where it calls "test" until the end of the calling sub. In the meantime, the test sub pauses 1 millisecond and continues itself?
 
Upvote 0
Almost. This was true if there was a call to Sleep in the first sub.

Watch the resumable subs video tutorial: https://www.b4x.com/etp.html
Hi, Errel, about yesterday's demo I posted, I am still somewhat confused about why "test ended" always appears at the end of the log. I mean, you can see from the log that the output of "count" costs about 18 milliseconds, while the time I specified in the sleep command is just 1 millisecond. If the "test" sub was resumed on time, then "test ended" should appear somewhere far before the end of the log. Why is this?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I mean, you can see from the log that the output of "count" costs about 18 milliseconds
Test it in release mode. It shouldn't take more than 1ms.

1. All your code is executed with a single thread.
2. The thread will not stop executing until it reaches a call to Wait For or Sleep, or when the event code completes.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Hi, Errel, about yesterday's demo I posted, I am still somewhat confused about why "test ended" always appears at the end of the log. I mean, you can see from the log that the output of "count" costs about 18 milliseconds, while the time I specified in the sleep command is just 1 millisecond. If the "test" sub was resumed on time, then "test ended" should appear somewhere far before the end of the log. Why is this?
Because Sleep() uses the apps event/message queue to process the delay. After calling Sleep(), as long as your app is processing code without relinquishing control, the event queue cannot be processed and your "test ended" will not log. Once you stop processing (in this case exiting the AppStart sub), the event/message queue can resume processing and your app logs the "test ended" line.

Links:
 
Upvote 0
Hi, Erel, thanks for your advice. Sadly, "test ended " still appeared at the end.
Test it in release mode. It shouldn't take more than 1ms.

1. All your code is executed with a single thread.
2. The thread will not stop executing until it reaches a call to Wait For or Sleep, or when the event code completes.
 
Upvote 0
Because Sleep() uses the apps event/message queue to process the delay. After calling Sleep(), as long as your app is processing code without relinquishing control, the event queue cannot be processed and your "test ended" will not log. Once you stop processing (in this case exiting the AppStart sub), the event/message queue can resume processing and your app logs the "test ended" line.

Links:
Hi, thanks for sharing your knowledge. So far, I think your explanation makes sense. If that's the case, then the time setting for sleep() won't work properly unless the time cost for the codes in the parent sub(in this case the AppStart sub) is smaller than the specified time. Do you think it is a bug? 🤔
 
Upvote 0
Not sadly as this is the expected behavior.
I asked you to run it in release mode as it is not reasonable for the code in AppStart to take 18ms.

Reread OliverA and my posts above to understand why it is the expected behavior.
OK, I will reread it more times, maybe I wasn't careful enough when I read them. My computer is very old and slow, I bought it 12 years ago. I guess that is why the codes in AppStart took 18ms.
 
Upvote 0
There is no bug here.

I think that it will be easier to help you if you start a new thread and explain what you are trying to do.
You are right. I think I am too arbitrary for saying it is a bug, I am sorry. The effect I want is that the "test" sub will be resumed immediately when the specified time is due.
 
Upvote 0
Top