Managing threads in a service

Giganews Newsgroups
Subject: Managing threads in a service
Posted by:  Clement Doss (cdo…@dhs.com.br)
Date: Mon, 1 Aug 2011

Hi,

I'm using DXE.

I'm creating a thread when the service starts and calls Terminate at stop.

There's a list of worker threads that is managed by a TThreadList.

  FMyList : TThreadList;

When I need to create a new worker thread, I use :

  FMyList.Add( TMyWorkerThread.Create( SomeID, Event_ThreadDone ) );

The event_ThreadDone is supposed to remove the Worker Thread from the list:

procedure TMyThread.event_ThreadDone(Sender : TObject);
begin
    FMyList.RemoveItem(Sender , FromBeginning );
end;

When the service stops, I run the following command:

procedure TMyThread.Stop;
var
  hndArray : THandleArray;
  hdnArraySize : Integer;
begin
    Terminate;
    FWaitEvent.SetEvent;

    BuildThreadHandleArray( hdnArraySize, hndArray );
    TerminalAllThreads; // Terminar todas processamentos de cubos
    WaitForMultipleObjects( hdnArraySize, @hndArray, true, INFINITE );
end;

procedure TMyThread.TerminalAllThreads;
var
  L : TList;
  i: Integer;
begin
  L :=  FMyList.LockList;
  try
    for i := 0 to L.Count-1 do
        TMyWorkerThread( L[i] ).Cancel
  finally
    FMyList.UnlockList;
  end;
end;

In the workerThread there's a loop in the execute method like:

While (not Done) and (not FCancel) do begin

end;

procedure TMyWorkerThread.Cancel;
begin
  FCancel := True;
end;

The service is not stable. After a few hours it's no longer possible to stop it.
And from my application log message, it's like the Event_ThreadDone is not
executed properly every time. The service never reach 100% CPU, it stays at 0%
and goes up to 10%.
When debuging, the worker thread ends as expected.
When I stop the service after a few minutes, it all goes well.
I guess I'm not using TThreadList correctly :(

What am I missing?

Clément

Replies