Oft will man, dass ein Thread nicht 100% seiner Zeit die CPU belastet, sondern nur alle paar Millisekunden etwas macht.
Das sieht dann so aus:
Code: Alles auswählen
procedure TMyThread.Execute;
begin
while not Terminated do
begin
Sleep(50);
// Mach was Nettes
end;
end;Code: Alles auswählen
destructor TMyThread.Destroy;
begin
Terminate;
WaitFor();
inherited Destroy;
end;Die Ursache liegt auf der Hand: Die Threads schlummern alle innerhalb von Sleep(50); und bekommen vom Terminate natürlich nichts mit. So vergehen pro Thread deutlich mehr als 25ms, völlig nutzlos. Natürlich könnte man in der Struktur die alle alle Thread hält, erst einen Loop machen und für jeden Thread Terminate aufrufen und dann erst Free, aber schön ist das ja auch nicht.
Was tun?
Die Lösung ist recht einfach. Statt Sleep verwendet man (ich) RTLEventWaitFor(...,50); und in Destroy den Aufruf RTLEventSetEvent(...); um die Wartezeit zu beenden. Man benötigt nur den entsprechenden Zeiger auf die Event-Daten, muss diesen in Create erzeugen und in Destroy freigeben, also ein nur sehr übersichtlicher Mehraufwand:
Code: Alles auswählen
type
TMyThread = class(TThread)
private
FEvent : PRTLEvent;
(...)
end;
constructor TMyThread.Create(CreateSuspended: Boolean;
const StackSize: SizeUInt = DefaultStackSize);
begin
inherited Create(True); // Schlafend erzeugen
FEvent := RTLEventCreate; // Das Event anlegen
if not CreateSuspended then
Suspended := False; // Ausführung beginnen, wenn gewollt
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
RTLEventWaitFor(FEvent,50); // Statt sleep. Wenn das Event nicht gesetzt wird, läuft der Aufruf in den TimeOut
// Mach was Nettes
end;
end;
destructor TMyThread.Destroy;
begin
if not Terminated then
Terminate; // Thread terminieren, falls noch nicht geschehen
RTLEventSetEvent(FEvent); // Den Schlaf abbrechen
if Suspended then
Suspended := False; // Den Thread aufwecken, falls er suspendiert ist
WaitFor(); // Auf das Ende warten
RTLEventDestroy(FEvent); // Das Event wieder freigeben
inherited Destroy;
end; (Der Code ist teilweise kopiert aber nicht in einem separaten Testprojekt getestet, möglich, dass da noch kleinere Syntaxfehler schlummern).
Grüße aus Hildesheim.