Hi @ll,
ich bastel gerade einen EventThread (zumindest, solange mir jetzt niemand sagt, dass Delphi sowas schon mitliefert ^^). Was stelle ich mir darunter vor?
Ich stelle mir das so vor, dass der EventThread eine Liste von Events hat, die zu einem bestimmten Zeitpunkt ausgelöst werden sollen:
Delphi-Quellcode:
TEventThreadNotifier =procedure of object;
TEventThreadEvent =class
public
exectime: TDateTime;
command: TEventThreadNotifier;
end;
Diese Events halte ich in eine TObjectList (FEvents) fest:
Delphi-Quellcode:
TEventThread =class(TThread)
private
FEvents: TObjectList;
public
constructor Create;
destructor Destroy;
procedure Remove(item: TEventThreadNotifier);
procedure Add(const AExectime: TDateTime; const cmd: TEventThreadNotifier);
procedure Execute;
end;
Die Execute-procedure und Add-procedure vielen mir eigentlich recht leicht:
Delphi-Quellcode:
procedure TEventThread.Add(const AExectime: TDateTime; const cmd: TEventThreadNotifier);
var neu: TEventThreadEvent;
i: integer;
begin
Suspend;
neu :=TEventThreadEvent.Create;
neu.exectime :=AExectime;
neu.command :=cmd;
for i:=0 to FEvents.Count -1 do
begin
if TEventThreadEvent(FEvents[i]).exectime > AExectime then
begin
FEvents.Insert(i, neu);
exit;
end;
end;
FEvents.Add(neu);
Resume;
end;
procedure TEventThread.Execute;
var nextEvent: TEventThreadEvent;
diff: Integer;
begin
while not Terminated do
begin
if FEvents.Count = 0 then sleep(5000)
else
begin
nextEvent :=TEventThreadEvent(FEvents.Items[0]);
diff :=MilliSecondsBetween(now,nextEvent.exectime);
if diff <=10 then
begin
synchronize(nextEvent.command);
FEvents.Delete(0);
end;
if diff <=5000 then sleep(diff)
else sleep(5000);
end;
end;
end;
Oder auch nicht...? Kann es passieren, dass ich ein event vor das 0-te Element einfüge und dann beim löschen dieses Element lösche statt dem, dass ich gerade ausgeführt habe? Wie verhindere ich das am besten?
Und dann noch die Remove-procedure:
Von der Theorie her ja einfach:
Delphi-Quellcode:
procedure TEventThread.Remove(item: TEventThreadNotifier);
begin
FEvents.Remove(item);
end;
Aber da sehe ich auch schon wieder unschöne Effekte: Wenn ich mir das Objekt in der Execute-procedure schon geziogen habe und es dann lösche (TObjectList Freed es ja auch), dann kann ich so an schöne AVs kommen.
Wie verhindere ich solche Probleme geschickt?
Letzter Tipp: Drogen. Machen zwar nicht glücklich, geben einem aber wenigstens das Gefühl glücklich zu sein.
Have a lot of fun!