Timer is not working properly

Hi, guys,
I have a problem with timer that I never had before in RealStudio.
Let me give you an illustration.

  1. Create a window and place a timer.
  2. Set the timer’s behavior to Mode = OFF (via IDE) and period t0 100
  3. In the Timer’s Action put the following code
me.period=100
beep
  1. Run the project

You will hear no beeping because the timer is OFF

Now, change the Timer’s Mode to Single and run the project.

The Timer will be beeping 10 times per second even though it is supposed to beep only once (because the mode is Single).

Apparently, there is a problem with this class in Xojo.

Very frustrating - this is a so simple function and it used to work well in RealStudio.

I have checked this with Carbon framework - everything works the way it is supposed to.

This timer problem appears in Cocoa only - still very frustrating.

Looks like calling .Period in the Action event causes it to fire again. Avoid that and it’s fine.

What a brilliant idea - now it works.

Thank you very much, Jason!

This sounds like a bug and is worth a Feedback case.

RealStudio Cocoa framework behaves the same way. If this is a bug, it is a long lasting Cocoa-specific bug. Definitely need to be fixed.

Please make sure to enter a Feedback Case. Without a Feedback case it will get lost in the forum. Feedback is the “official” way to log bugs and feature requests.

I have some odd behavior in my current project. Having trouble reproducing it in a smaller test project. I set my timer to fire at 1 second intervals. When it fires I check a variable and if it’s set… 1st thing I do is turn off the timer…then I do other stuff. If the variable is not set…I just let the timer fire the action even again. Quite often I have the action event fire when the timer is set to Mode = “0” (Off). I placed a MsgBox in the Timer’s action event MsgBox("hello "+str(me.mode))
I see “Hello 2” and then “Hello 0” and sometimes again “Hello 0”. How can the event fire if the Mode is set to zero?

I too have an app/project with Timers that won’t work since moving to 2016 2.2 and 100% Cocoa and Yosemite

I moved from XOJO 2014 using Carbon target - to XOJO 2015 2.2 and 100% Cocoa recently.

One timer is used to feed the Apple CoreAudio output stream using the MBS Audio plugin.

I have a second "message“ timer set to 50 ms which regularly receives and reroutes internal app messages internally to update window GUI etc.

All used to be fine. I had an App.Doevents loop to ensure the main thread got enough cycles etc.

But now The "message“ timer stops “ticking” after around 3 ticks !

The timer which feeds the audio stream regularly ( 512 frame block size ) keeps running though.

I even tried the MBS timer and the MBS NSTIMER but they all fail.

This used all to work before

You should not use App.DoEvents in a desktop app. Ever. And certainly not to fire a Timer.

I wonder if that is part of the problem…

[quote=20445:@VALERIY KOZMENKO]Create a window and place a timer.
Set the timer’s behavior to Mode = OFF (via IDE) and period t0 100
In the Timer’s Action put the following code
me.period=100
beep

Now, change the Timer’s Mode to Single and run the project.

The Timer will be beeping 10 times per second even though it is supposed to beep only once (because the mode is Single).[/quote]

I am sorry, but I could not reproduce the issue. with what is described. Changing the period does not change the way the timer triggers. It does not start firing again.

However, changing the Mode in the Action event indeed resets the timer and makes it run again.

me.mode = Timer.ModeSingle me.period = 100

I bet that is what really happened.

It does not look like a bug to me. When one sets the mode, in effect, it restarts the Timer. It makes sense. If you set the mode to Multiple in a ModeSingle timer, you would expect it to fire multiple right away.

No idea if or why Carbon may have not done otherwise. And frankly I don’t care more than to know if it worked on 68000 or PPC. Life goes on. Carbon has been deprecated for long enough to let it rest in peace.

[quote=204542:@Daniel Stenning]I too have an app/project with Timers that won’t work since moving to 2016 2.2 and 100% Cocoa and Yosemite

I moved from XOJO 2014 using Carbon target - to XOJO 2015 2.2 and 100% Cocoa recently.

One timer is used to feed the Apple CoreAudio output stream using the MBS Audio plugin.

I have a second "message“ timer set to 50 ms which regularly receives and reroutes internal app messages internally to update window GUI etc.

All used to be fine. I had an App.Doevents loop to ensure the main thread got enough cycles etc.

But now The "message“ timer stops “ticking” after around 3 ticks !

The timer which feeds the audio stream regularly ( 512 frame block size ) keeps running though.

I even tried the MBS timer and the MBS NSTIMER but they all fail.

This used all to work before[/quote]

I checked your bug report. As it stands, with only your description, difficult to guess what is going on.

A sample project is probably the only way you are going to get any help. One thing is for sure, without a sample project that demonstrates the bug, Xojo engineers will not be able to figure out what is going on.

…even if the Mode value hasn’t changed. This has now been documented in the LR.

Sorry, to be clear, if Timer1 is set to ModeMultiple with a period of 1000, and Timer2 runs every 200 ms and only sets Timer1.Mode to ModeMultiple, Timer1 will never execute.

That again makes sense. Changing the mode every 200 ms resets Timer1 to 1000 ms and keeps pushing it back every 200 ms, so it never has a chance to fire.

It works just as well with Timer2 at 999 Ms. And as soon as Timer2.Enable = False, Timer1 fires.

Incidentally, it works exactly the same in Windows.

And yes, it is clearly documented in the Timer Mode part of the LR. Must be what happened to the OP.

Well, it’s clearly documented now… :slight_smile:

I’d still file a bug report because what it does may not be what its designed to do

I’m not sure setting the mode should behave like a reset

Even if it was a bug initially, since it’s been like that for a while (I think), it’s consistent across platforms (I guess, since I didn’t try Linux), and changing it now might break existing code, isn’t it a “feature” now anyway?

It does when you go from one mode to another ; for instance from Off to ModeSingle or ModeMultiple, when it starts the timer.

It behaves exactly the same in Mac OS X El Capitan, Windows 10 and LinuxMint. IMHO, it works just as it should. If the timer did not reset when mode changes, it would never start when changing from off to single or multiple. In the new framework, Enabled has been abandoned, and it is the same. All that seems pretty consistent to me.

[quote=204545:@Kem Tekinay]You should not use App.DoEvents in a desktop app. Ever. And certainly not to fire a Timer.

I wonder if that is part of the problem…[/quote]

[quote=204545:@Kem Tekinay]You should not use App.DoEvents in a desktop app. Ever. And certainly not to fire a Timer.

I wonder if that is part of the problem…[/quote]

er… I’ll quote Charles Yeomans - i’m well aware of the Doevents don’ts but in some cases you cannot avoid it. AND I’v tried putting things into threads. :

Re: App.currentThread.sleep vs app.doEvents
Date: 19.03.08 19:40 (Wed, 19 Mar 2008 14:40:42 -0400)
From: Charles Yeomans

On Mar 18, 2008, at 4:20 PM, Kimball Larsen wrote:

Occasionally I find that I need to pause a particular method while I
wait for something else asynchronous to happen. Case in point:

I am currently working on a networking app. This app needs to send a
command to a TCPSocket, and then wait for the response to come in from
the client.
This waiting period will be an indeterminate amount of time, so here
is what I do:

I set a little flag to indicate that I’m waiting for a response now:
me.waitingToReceive = true
Send the data:
me.write(“5000:”)
me.flush
Then sit and wait for the DataAvailable event to fire, which sets
waitingToReceive = false
while me.waitingToReceive = true
app.CurrentThread.Sleep(10)
wend

My question is this: What should I do in that while loop?
App.doEvents? app.CurrentThread.sleep(n)? Nothing?

This is one of the reasonable uses of app.DoEvents. I’ve implemented
synchronous methods in this way in console apps. I expect that it
would work in GUI apps as well.

Charles Yeomans