dexter 0 Posted June 30, 2020 (edited) Hi, In a console application I have defined a timed task, which sends an empty string once per minute to keep alive a connection: FKeepAlive := Parallel.TimedTask.Every(60 * 1000).Execute( procedure() begin FConn.SendStr(''); // will send just ENTER each minute end ); When the application is closing - I'm trying to stop the task with following code: FKeepAlive.Stop; FKeepAlive.Terminate(5000); // <-- here error is raised And I'm getting System Error: Invalid window handle How is the proper way to stop a timed task? Edited June 30, 2020 by dexter Share this post Link to post
Sonjli 6 Posted June 30, 2020 Hi, I think your problem is FConn. It seems a class field, and maybe it is destroyed before the timer ends? Regards, Eddy Share this post Link to post
dexter 0 Posted July 1, 2020 Hi, The full destructor code is: destructor TjBASEComm.Destroy; begin if Assigned(FKeepAlive) then try FKeepAlive.Stop; FKeepAlive.Terminate(5000); // <-- here error is raised except end; try FConn.Free; except end; inherited; end; As you can see - connection is freed after. Can it be because application is a console app? Share this post Link to post
Sonjli 6 Posted July 1, 2020 The only problem I know about console apps is about "omni messaging system". Look at documentation http://www.omnithreadlibrary.com/book/chap05.html#introotl-messagelooprequired-console Maybe after 5 seconds the parallel timer is not terminated. Try this: destructor TjBASEComm.Destroy; begin if Assigned(FKeepAlive) then try FKeepAlive.Stop; FKeepAlive.Terminate; FKeepAlive.WaitFor; // This wait until the task is REALLY terminated. If it is stuck then the problem is elsewhere except end; try FConn.Free; except end; inherited; end; There is also a doubt about "FConn.SendStr('')": what does it do? Regards, Eddy Share this post Link to post
dexter 0 Posted July 2, 2020 Hi Eddy, the problem is not in FConn. I have removed the call to FConn.SendStr('') from TimedTask execution, and the problem persists. And exception is raised during FKeepAlive.Terminate, FKeepAlive.WaitFor does not help. See attached the call stack to exception. Share this post Link to post
Sonjli 6 Posted July 2, 2020 Hi, I am pretty sure the problem is related to this: http://www.omnithreadlibrary.com/book/chap05.html#introotl-messagelooprequired-console Regards, Eddy Share this post Link to post
dexter 0 Posted July 2, 2020 Hi, I have updated the destructor but it did not help: FKeepAlive.Stop; while integer(PeekMessage(Msg, 0, 0, 0, PM_REMOVE)) <> 0 do begin TranslateMessage(Msg); DispatchMessage(Msg); end; FKeepAlive.Terminate(5000); And it fails during call to Terminate(5000) after about 1 second. Share this post Link to post
Sonjli 6 Posted July 2, 2020 Ok, this is my last chance... after this you must wait for @Primož Gabrijelčič Try something like this: procedure ProcessMessages; var Msg: TMsg; begin while integer(PeekMessage(Msg, 0, 0, 0, PM_REMOVE)) <> 0 do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end; ... FKeepAlive.Stop; repeat ProcessMessages; until FKeepAlive.Terminate(1000); ... Share this post Link to post
dexter 0 Posted July 3, 2020 Same problem, fails with Invalid Window Handle during first .Terminate(1000) call. Share this post Link to post
Primož Gabrijelčič 223 Posted July 8, 2020 Can I get a minimal reproducible example project, please? Share this post Link to post