Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Terminating Thread in android service



Permlink Replies: 4 - Last Post: Apr 27, 2017 9:43 AM Last Post By: drama mix
drama mix

Posts: 37
Registered: 6/27/12
Terminating Thread in android service
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 26, 2017 7:32 AM
i have this running Thread in android service


 
constructor TCThread.Create(CreateSuspended: Boolean; aThreadCallbackProc: TThreadCallbackProc; AConn: TIdTCPConnection);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := False;
FOnCallbackProc := aThreadCallbackProc;
FTCP := AConn;
 
 
end;
 
procedure TCThread.Execute;
begin
 
while not Terminated and FTCP.Connected do
begin
 
FCommand := FTCP.Socket.ReadLn;
try
Sleep(5);
ProcessCommands;
 
finally
FCommand := '';
end;
 
end;
 
 
 
end;


but when ever i stop the service the whole app get crashed i do call terminate thread on service destroy like following

procedure TAndroidServiceDM.AndroidServiceDestroy(Sender: TObject);
begin
 
 
if tcpc.Connected then
begin
tcpc.Disconnect;
end;
 
 
if Assigned(CThread) then
begin
CThread.Terminate;
FreeAndnil(CThread);
end; 
 
end;


what iam doing wrong ?
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Terminating Thread in android service
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 26, 2017 8:56 AM   in response to: drama mix in response to: drama mix
Am 26.04.2017 um 16:32 schrieb drama mix:
i have this running Thread in android service

 
 
constructor TCThread.Create(CreateSuspended: Boolean; aThreadCallbackProc: TThreadCallbackProc; AConn: TIdTCPConnection);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := False;
FOnCallbackProc := aThreadCallbackProc;
FTCP := AConn;
 
 
end;
 
procedure TCThread.Execute;
begin
 
while not Terminated and FTCP.Connected do
begin
 
FCommand := FTCP.Socket.ReadLn;
try
Sleep(5);
ProcessCommands;
 
finally
FCommand := '';
end;
 
end;
 
 
 
end;


but when ever i stop the service the whole app get crashed i do call terminate thread on service destroy like following

procedure TAndroidServiceDM.AndroidServiceDestroy(Sender: TObject);
begin
 
 
if tcpc.Connected then
begin
tcpc.Disconnect;
end;
 
 
if Assigned(CThread) then
begin
CThread.Terminate;
FreeAndnil(CThread);
end; 
 
end;


what iam doing wrong ?

Maybe the thread is not completely terminated yet when your FreeAndNil
is being carried out?

And is FCommand := FTCP.Socket.ReadLn; a blocking call?

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Terminating Thread in android service
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 26, 2017 12:52 PM   in response to: Markus Humm in response to: Markus Humm
Markus wrote:

Maybe the thread is not completely terminated yet when
your FreeAndNil is being carried out?

Agreed, However, remember that this is on mobile, so FreeAndNil() is really
not freeing the thread object, it is just decrementing the object's reference
count. While the thread is actually running, TThread maintains an internal
reference to itself so its refcount cannot fall to 0 until after the thread
has terminated.

And is FCommand := FTCP.Socket.ReadLn; a blocking call?

By default, yes.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Terminating Thread in android service
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 26, 2017 12:50 PM   in response to: drama mix in response to: drama mix
drama wrote:

but when ever i stop the service the whole app get crashed i
do call terminate thread on service destroy like following

You are not waiting for the thread to fully terminate. You need to call
CThread.WaitFor() after calling CThread.Terminate():

procedure TAndroidServiceDM.AndroidServiceDestroy(Sender: TObject);
begin
  if tcpc.Connected then
  begin
    tcpc.Disconnect;
  end;
  if Assigned(CThread) then
  begin
    CThread.Terminate;
    CThread.WaitFor; // <-- add this!
    FreeAndnil(CThread);
  end;
end;


But more importantly, TIdIOHandler.ReadLn() is a blocking operation, so it
is possible that the thread may not even terminate at all if it is waiting
for data to arrive from the remote peer. And closing the socket from another
thread is not guaranteed to abort a socket operation in progress, either.
So I suggest you specify a timeout for ReadLn() so that it will exit after
awhile if no data arrives, thus allowing the thread to check its Terminated
property periodically:

procedure TCThread.Execute;
begin
  while (not Terminated) and FTCP.Connected do
  begin
    FCommand := FTCP.Socket.ReadLn(LF, 1000);
    if not FTCP.Socket.ReadLnTimedOut then
    try
      Sleep(5);
      ProcessCommands;
    finally
      FCommand := '';
    end;
  end;
end;


--
Remy Lebeau (TeamB)
drama mix

Posts: 37
Registered: 6/27/12
Re: Terminating Thread in android service
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 27, 2017 9:43 AM   in response to: drama mix in response to: drama mix
Thank you very much
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02