Einzelnen Beitrag anzeigen

Benutzerbild von yankee
yankee

Registriert seit: 10. Mär 2004
1.134 Beiträge
 
Lazarus
 
#1

TThread: Ein paar Fragen zum Umgang damit...

  Alt 9. Mär 2007, 21:33
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!
  Mit Zitat antworten Zitat