I’ve noticed some oddities in application load when I’m sleeping a current thread. In the thread, if I call App.SleepCurrentThread(ms), the thread sleeps and the main loop is very responsive. However, if I call me.Sleep(ms) at that same point in the loop, the main loop is variable in response and the activity monitor reports that the app is using more CPU than with the App.SleepCurrentThread call.
Is this expected?
Sounds like it might be a bug. Can you say more? What xojo version, what OS, etc?
Also, are you using the WakeEarly = true option? See https://documentation.xojo.com/index.php/Thread.Sleep
Sorry - it goes back to 2017 and is still present in 2018r2. This is on Mac OS and Linux 64bit builds.
One thing to remember… Thread.Sleep tells the thread exactly where you want it to sleep. App.SleepCurrentThread tells the thread to sleep right now, regardless of what its doing. It could be in the middle of a long running loop for instance. My thought here is that what you are experiencing is expected behavior and that its just a matter of timing.
That is where this occurs. For instance when I need to flush a device connection before trying to retrieve more data.
Would you please explain the difference? It seems like they should be doing the same thing.
You can call Thread.sleep from outside the thread, which will put the thread to sleep wherever it may have yielded (e.g. at the top of a for/next loop, at an explicit Yield call, etc…)
You can only call app.sleepCurrentThread from within the thread itself, which means that the thread yield right there.
Perhaps that what Greg is referring to?
Edit - as an example:
for i as integer = 1 to 100 //A
me.Yield // B
for j as integer = 1 to 100 //C
app.SleepCurrentThread (1) // D
MyDatabase.DoSomethingWhichMightYield() // E
If you call Thread1.Sleep() from outside the thread, you can find that it has yielded at A, B, C, D, or E
Whereas the call to app.SleepCurrentThread() will always yield at D and only at D.
You can also call Self.Sleep(ms) from within the thread. What I was getting at though is that calling it from within the thread object and from outside the current thread can result in two completely different behaviors. That is, calling from within, you are deciding when and where it pauses, whereas from the outside its probably on a loop boundary, whichever it hits next.
Think of two nested loops. If you sleep only on the outer one within the thread, the entire inner loop would always complete. If you were to call Thread1.sleep from the outside it may also pause the inner loop.
The inner one could yield to another thread though - even if you didn’t call sleep. I think your example may be true, but only in an app with one thread running.
In my case. I am calling it from within the thread in both cases. As I said, I replace one with the other in the exact same spot.
Loop Until Not theShell.IsRunning
I’ve never had a need to call Thread.Sleep from outside the thread, so I assumed Tim meant calling both from within the thread. There I would expect them to function identically.
… and it appears that they don’t.