Ein paar Gedanken von mir dazu:
- du gibst nirgendwo die TObjectList Instanz wieder frei aus dem Thread
- du gibst nirgendwo beendete Threads wieder frei
- vergleiche niemals auf true
- warum ist der Constructor des Threads virtuell?
- du benutzt die Terminate Methode falsch, da diese nur das Terminated Flag setzt und somit eine Kennzeichnung für den Nutzer von TThread sein soll, die Execute-Methode zu verlassen.
Und dein Hauptfehler:
- du lässt den Thread sofort loslaufen, und das bevor der Constructor abgearbeitet ist und somit bevor die ObjectList Instanz gebildet wurde.
Zu deinem Edit: alle Member einer Klasse sowie globale Objekte werden auf ordinal 0 initialisiert.
/EDIT: nochmal alle Hinweise umgesetzt:
Delphi-Quellcode:
type
TSampleThread= class(TThread)
TestList: TObjectList;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;
constructor TSampleThread.Create;
begin
inherited Create(true);
FreeOnTerminate := False;
TestList := TObjectList.Create;
Resume;
end;
destructor TSampleThread.Destroy;
begin
TestList.Free;
inherited;
end;
procedure TSampleThread.Execute;
var j, Rnd: integer;
begin
j := 1;
while not Terminated and ( j < 10 ) do
begin
Rnd := Random(TestList.Count + 10);
inc(j);
end;
end;
Delphi-Quellcode:
TThreadManager = class
public
Thread: array[1..20] of TSampleThread;
procedure Add;
end;
procedure TThreadManager.Add;
var
i: integer;
FreeSlot: boolean;
begin
i := 0;
FreeSlot := False;
repeat
inc(i);
FreeSlot := ( assigned(Thread[i]) and Thread[i].Terminated )
or not assigned(Thread[i]);
until FreeSlot or (i = 20);
if FreeSlot then
begin
Thread[i].Free;
Thread[i] := TSampleThread.Create;
end;
end;