views:

234

answers:

4

Hello all,

As you can tell, I am having a little trouble with the TTimer VCL component within my application developed using Delphi 2010.

Whenever I call:

Self.Timer1.Enabled := False;
Self.Timer1.Enabled := True;

The timer component does seem to indeed halt, but, it never starts up again. Like, it never calls the OnTimer event.

I am using it in conjunction with the Indy10 IRC component (TIdIRC).

Thanks in advance :)

+3  A: 

You are also aware that most Indy calls are blocking? A timer works by sending Windows Messages which means the messages need to be processed in order for the timer to fire. If the application/main thread blocks it does not process messages and timers do not get fired. Maybe this is your problem?

Also if your application is a Windows Service or a console application the messages might not be processed.

Lars Truijens
Basically, I'm making a quiz bot. After every X milliseconds (10000/10 seconds), it will give out a hint. If a user gets' the question correct, it will stop the timer (by the above method) and will go and give out the next question. Hope I made sense :/
How can I fix it if this is the case?
Use threads or don't use Indy. Don't use TTimer in a Windows Service or a console application.
Lars Truijens
+2  A: 

Take Indy out of the equation and see if you can get it to basically throw up the hint every 10 seconds. If not, you're doing something wrong. Like mis-interpreting the interval time. For instance, "(10000/10 seconds)" is not very clear. I think you mean "10000ms which is 10 seconds" but you don't show your code, so I can only guess. Delphi won't guess, it will do what you tell it. Anyway, make a sample app with a form, button, edit box and a ttimer and experiment. Get the timer stuff working, before you introduce the Indy stuff. Then you know whether you've got a TTimer problem or an Indy problem.

Chris Thornton
Okay, I forgot to mention that the Timer calls the OnTimer event every 10 seconds. It works when I don't modify the enabled state but until I do, it stops calling the OnTimer event :/
A: 

You must make sure that you call these methods of TTimer only in the context of the main thread. Since Indy uses threads it may well be the case that this rule is violated. To find out easily you can call Assert when the code is executed in the context of another thread:

Assert(GetCurrentThreadId = MainThreadId);
Self.Timer1.Enabled := False;
Self.Timer1.Enabled := True;

I don't know what Self is referring to in your code, but it's worth trying.

mghie
Self refers to the form class.
I tried that. It didn't raise any Assertion errors.
A: 

I created a Timer in a separate thread and everything is working well again :)

Thanks guys, I learned a lot of stuff.