Recent

Author Topic: TTimer stops after wake from sleep state  (Read 1305 times)

karloromic

  • New Member
  • *
  • Posts: 32
TTimer stops after wake from sleep state
« on: September 16, 2019, 01:56:42 pm »
Why TTimer stops after waking up from sleep state?
I have a TTimer that runs every 5 seconds to check for network connectivity by creating thread every time (when thread starts TTimer is disabled) and TTimer is reenabled on thread finished.

Windows 10 x64
Lazarus x32 2.0.4

rvk

  • Hero Member
  • *****
  • Posts: 3836
Re: TTimer stops after wake from sleep state
« Reply #1 on: September 16, 2019, 03:17:19 pm »
I'm not sure about your TTimer problem (it's probably not re-enabled)... but why are you using a TTimer in this case? Isn't it easier to just use the thread and do the check in a loop with 5 seconds sleep.

karloromic

  • New Member
  • *
  • Posts: 32
Re: TTimer stops after wake from sleep state
« Reply #2 on: September 16, 2019, 03:37:06 pm »
I'm not sure about your TTimer problem (it's probably not re-enabled)...

Yeah i figured it out by testing other timer which is enabled all the time (works fine after wake).

why are you using a TTimer in this case? Isn't it easier to just use the thread and do the check in a loop with 5 seconds sleep.


Yes it would be easier, what would be the best way to create that loop, simplest as posible?
Something like this?
repeat
    DoSomethingHere(x);
    x := x + 1;
    sleep(5000);
  until x = 10;

but i need it running indefinitely
« Last Edit: September 16, 2019, 03:41:27 pm by karloromic »

rvk

  • Hero Member
  • *****
  • Posts: 3836
Re: TTimer stops after wake from sleep state
« Reply #3 on: September 16, 2019, 03:40:51 pm »
Code: Pascal  [Select]
  1. procedure TMyThread.Execute;
  2. begin
  3.   while not Terminated { and MaybeSomeOtherConditionIfNeeded } do
  4.   begin
  5.     // DoYourCheck
  6.     Sleep(5000);
  7.   end;
  8. end;

Terminating the thread will set Terminated to true so the loop will end (during your TThread.WaitFor).

karloromic

  • New Member
  • *
  • Posts: 32
Re: TTimer stops after wake from sleep state
« Reply #4 on: September 16, 2019, 03:43:56 pm »
Code: Pascal  [Select]
  1. procedure TMyThread.Execute;
  2. begin
  3.   while not Terminated { and MaybeSomeOtherConditionIfNeeded } do
  4.   begin
  5.     // DoYourCheck
  6.     Sleep(5000);
  7.   end;
  8. end;

Terminating the thread will set Terminated to true so the loop will end (during your TThread.WaitFor).

Wouldn't Execute method run only once and then stop/terminate?

rvk

  • Hero Member
  • *****
  • Posts: 3836
Re: TTimer stops after wake from sleep state
« Reply #5 on: September 16, 2019, 03:45:30 pm »
Wouldn't Execute method run only once and then stop/terminate?
Not if you put a while-loop in there  :D

That's the 'normal' place to do it in a thread.

See the examples on this page: https://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial

karloromic

  • New Member
  • *
  • Posts: 32
Re: TTimer stops after wake from sleep state
« Reply #6 on: September 16, 2019, 03:49:08 pm »
Wouldn't Execute method run only once and then stop/terminate?
Not if you put a while-loop in there  :D

That's the 'normal' place to do it in a thread.

See the examples on this page: https://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial


Sorry, didnt see while there, my mistake  :D
Thank you very much! :)

Thaddy

  • Hero Member
  • *****
  • Posts: 8955
Re: TTimer stops after wake from sleep state
« Reply #7 on: September 16, 2019, 05:01:48 pm »
stop and start do also magic....
Most people that want to use threading should learn to patch their jeans first: use a needle.

rvk

  • Hero Member
  • *****
  • Posts: 3836
Re: TTimer stops after wake from sleep state
« Reply #8 on: September 16, 2019, 05:09:00 pm »
stop and start do also magic....
TThread.Stop ???? Does that one really exist?

karloromic

  • New Member
  • *
  • Posts: 32
Re: TTimer stops after wake from sleep state
« Reply #9 on: September 16, 2019, 08:59:47 pm »
stop and start do also magic....
TThread.Stop ???? Does that one really exist?

Looking through documentation and source code, it doesn't.

ASerge

  • Hero Member
  • *****
  • Posts: 1408
Re: TTimer stops after wake from sleep state
« Reply #10 on: September 16, 2019, 10:33:46 pm »
Why TTimer stops after waking up from sleep state?
Project with one TTimer and code
Code: Pascal  [Select]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. begin
  3.   Caption := TimeToStr(Time);
  4. end;
shows the time and after sleep.

rvk

  • Hero Member
  • *****
  • Posts: 3836
Re: TTimer stops after wake from sleep state
« Reply #11 on: September 16, 2019, 11:17:34 pm »
Why TTimer stops after waking up from sleep state?
Project with one TTimer and code
Code: Pascal  [Select]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. begin
  3.   Caption := TimeToStr(Time);
  4. end;
shows the time and after sleep.
The problem probably lies in the fact that the ttimer is disabled when the thread is started and enabled again when the thread ends. So the problem is not in the ttimer but in the detection of the end of the thread. And without any sample code it's hard to find out what.

winni

  • Sr. Member
  • ****
  • Posts: 339
Re: TTimer stops after wake from sleep state
« Reply #12 on: September 16, 2019, 11:49:06 pm »
@karloromic:

I think you make yourself things complicated.

The timer wakes up all n milliseconds - 5000 in your case.

You don't need to start a thread to detect your network connection. Just place the code inside the procedure  Timer1Timer.  Then you have all that you need.

If you insist on using a thread then set on creating the thread

Code: Pascal  [Select]
  1. FreeOnTerminate := True;

Then you don't have to free the thread when he is finished.

That's all.

Winni

karloromic

  • New Member
  • *
  • Posts: 32
Re: TTimer stops after wake from sleep state
« Reply #13 on: September 17, 2019, 12:19:30 am »
@karloromic:

I think you make yourself things complicated.

The timer wakes up all n milliseconds - 5000 in your case.

You don't need to start a thread to detect your network connection. Just place the code inside the procedure  Timer1Timer.  Then you have all that you need.

If you insist on using a thread then set on creating the thread

Code: Pascal  [Select]
  1. FreeOnTerminate := True;

Then you don't have to free the thread when he is finished.

That's all.

Winni

If i place the code inside procedure OnTimer then the application freezes until connection is made and all checks return result, that can take up to 10 seconds depending on connection speed and latency, and for all that time my program would be frozen.

Code: Pascal  [Select]
  1. //set on creating the thread
  2. FreeOnTerminate := True;
I did.

TTimer works fine as stated by ASerge and also tested by me the same way.
The problem is in my code.
My source code is too big to be pasted here but i can explain.

- TTimer is created and its interval value is 5000 and is enabled on form create

Repeating this
- OnTimer disables itself and starts new Thread(CreateSuspended)
- Thread.OnCreate calls inherited Create(CreateSuspended) and sets
  FreeOnTerminate := True;
- OnTimer Starts the thread
- Thread execute internet check code and on the end of Execute updates data to form with Synchronize(@UpdateStatus);
- UpdateStatus method updates data and when finished updating data, enables TTimer again
End Repeat

You can imagine Sleep and Wake event in any time of this code
« Last Edit: September 17, 2019, 12:21:17 am by karloromic »

winni

  • Sr. Member
  • ****
  • Posts: 339
Re: TTimer stops after wake from sleep state
« Reply #14 on: September 17, 2019, 12:54:58 am »
@karloromic:

Okay, I think you like this complicated stuff.

But the problem is at only one point:

If you do a synchronous call to the net you will always have a problem if you wait for connection. And the UI freezes.

So the one solution is to do an asynchronous call to the net in a loop until you get a connection.

Or you make a synchrous call with a short timeout until you get a connection. Or give up.

I use  for checking this simple function made with the help of netdb and Sockets - two FPC units:

Code: Pascal  [Select]
  1. function HostByName (const who : string; var IP : String): Boolean;  inline;
  2. Var H : THostEntry;
  3.   begin
  4.     result := ResolveHostByName(who,H);
  5.     if result then IP := HostAddrToStr(H.Addr) else IP := '';
  6.   end;                      
  7.  

So you can call for something that is always up: Google or Amazon, so that they this time do something useful.
Perhaps you can even adjust the timeout.

Winni