Jump to content
dexter

Stopping a TimedTask

Recommended Posts

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 by dexter

Share this post


Link to post

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

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

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

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.

Annotation 2020-07-02 094725.png

Share this post


Link to post

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

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

Same problem, fails with Invalid Window Handle during first .Terminate(1000) call.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×