Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi TEvent.free im Thread Destructor? (https://www.delphipraxis.net/180451-tevent-free-im-thread-destructor.html)

Mavarik 21. Mai 2014 12:20

TEvent.free im Thread Destructor?
 
Hallo Zusammen.

Gegeben sei ein Thread der ein
Delphi-Quellcode:
MyEvent := TEvent...
handle hat.
Delphi-Quellcode:
Procedure TMyThread.Execute;
begin
  While not Terminated do
   begin
     MyEvent.WaitFor(infinite);
     if not(Terminated) then
       begin
         // Mach was schlaues...
       end;
   end;
end;

Destructor TMyThread.destroy;
begin
  Terminate;
  MyEvent.SetEvent;
  MyEvent.Free;     // Gut oder schlecht???
  Inherited;
end;
Mavarik

Dejan Vu 21. Mai 2014 12:28

AW: TEvent.free im Thread Destructor?
 
Delphi-Quellcode:
if Mavarik.Erstellt(MyEvent).Im(Konstruktor) then
  result := Gut
else
  result := Not Gut;

Mavarik 21. Mai 2014 12:33

AW: TEvent.free im Thread Destructor?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1259624)
Delphi-Quellcode:
if Mavarik.Erstellt(MyEvent).Im(Konstruktor) then
  result := Gut
else
  result := Not Gut;

LOL...

Delphi-Quellcode:
Constructor TMyThread.Create;
begin
  inherited Create(true);

  MyEvent := TEvent.Create(NIL,false,false,'');
  ....
end;

Const
  Mavarik = Gut;
Danke

PS.: Die eigentliche Frage war, wird bei MyEvent.SetEvent der Thread sofort gestartet oder kann es sein, dass die
MyEvent.WaitFor(Infinite); plötzlich keinen Rücksprung mehr hat.

Der schöne Günther 21. Mai 2014 12:58

AW: TEvent.free im Thread Destructor?
 
Der Punkt ist folgender: Dein Thread läuft. Er ist zwar nicht sonderlich aktiv und wartet bis zum Tag des jüngsten Gerichts dass
Delphi-Quellcode:
myEvent
eintritt, aber er ist gestartet.

Wenn du ihn terminierst, läuft er weiter. Und weiter. Denn er wartet auf das Event.

Daher würde ich in deinem Thread noch die Methode
Delphi-Quellcode:
TerminatedSet
überschreiben: Diese sollte sich um das Setzen des Events kümmern, damit der Thread nicht ewig dort in seinem Execute darauf wartet, sollte es nie eingetreten sein.

Siehe auch hier: http://www.delphipraxis.net/1254537-post13.html

Mavarik 21. Mai 2014 13:49

AW: TEvent.free im Thread Destructor?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1259630)
Der Punkt ist folgender: Dein Thread läuft. Er ist zwar nicht sonderlich aktiv und wartet bis zum Tag des jüngsten Gerichts dass
Delphi-Quellcode:
myEvent
eintritt, aber er ist gestartet.

Wenn du ihn terminierst, läuft er weiter. Und weiter. Denn er wartet auf das Event.

emm... Nein...

Deswegen mache ich ja ein
Delphi-Quellcode:
   MyEvent.SetEvent;

jaenicke 21. Mai 2014 13:53

AW: TEvent.free im Thread Destructor?
 
Terminate gehört eigentlich nicht in den Destruktor, der ist rein zum Aufräumen da. Oder wenn es dort schon steht, sollte dann ein WaitFor auf den Thread folgen, in diesem Fall nach dem SetEvent. Danach kannst du ruhigen Gewissens alles freigeben.

Bei mir steht die Sequenz Terminate, WaitFor, Free außerhalb des Threads.

Sir Rufo 21. Mai 2014 14:00

AW: TEvent.free im Thread Destructor?
 
So ist es richtig und ausreichend:
(Ich habe mir erlaubt aus
Delphi-Quellcode:
MyEvent
ein
Delphi-Quellcode:
FMyEvent
um zu verdeutlichen, dass es sich um ein Feld der Klasse handelt)
Delphi-Quellcode:
procedure TMyThread.TerminatedSet;
begin
  inherited;
  FMyEvent.SetEvent; // auf jeden Fall auch NACH INHERITED!!!!
end;

Procedure TMyThread.Execute;
begin
  While not Terminated do
   begin
     FMyEvent.WaitFor(infinite);
     if not(Terminated) then
       begin
         // Mach was schlaues...
       end;
   end;
end;

Destructor TMyThread.destroy;
begin
  Inherited;
  FMyEvent.Free; // NACH INHERITED!!!!!!
end;
Wen man wissen möchte, warum das reicht, dann schaut man sich den Source von
Delphi-Quellcode:
TThread.Destroy
einfach mal an (so habe ich auch herausgefunden, warum das so ausreicht) und sieht dort folgende lustige Dinge:
Delphi-Quellcode:
destructor TThread.Destroy;
begin
  if (FThreadID <> 0) and not FFinished and not FExternalThread then
  begin
    Terminate;
    if FCreateSuspended or FSuspended then
      Resume;
{$IFDEF MSWINDOWS}
    while not FStarted do
{$ELSE}
    while not ((not FCreateSuspended or FInitialSuspendDone) and FStarted) do
{$ENDIF}
      Yield;
    WaitFor;
  end;
  ...
end;

Mavarik 21. Mai 2014 14:05

AW: TEvent.free im Thread Destructor?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1259641)
So ist es richtig und ausreichend:
(Ich habe mir erlaubt aus
Delphi-Quellcode:
MyEvent
ein
Delphi-Quellcode:
FMyEvent
um zu verdeutlichen, dass es sich um ein Feld der Klasse handelt)
Delphi-Quellcode:
procedure TMyThread.TerminatedSet; // Erst ab XE? jedenfalls gibt es das nicht in D2007
begin
  inherited;
  FMyEvent.SetEvent;
end;

Procedure TMyThread.Execute;
begin
  While not Terminated do
   begin
     FMyEvent.WaitFor(infinite);
     if not(Terminated) then
       begin
         // Mach was schlaues...
       end;
   end;
end;

Destructor TMyThread.destroy;
begin
  Inherited;
  FMyEvent.Free; // NACH INHERITED!!!!!! Stimmt hab ich auch gefunden!
end;

s.o.

Mavarik 21. Mai 2014 14:06

AW: TEvent.free im Thread Destructor?
 
Zitat:

Zitat von jaenicke (Beitrag 1259639)
Terminate gehört eigentlich nicht in den Destruktor, der ist rein zum Aufräumen da. Oder wenn es dort schon steht, sollte dann ein WaitFor auf den Thread folgen, in diesem Fall nach dem SetEvent. Danach kannst du ruhigen Gewissens alles freigeben.

Bei mir steht die Sequenz Terminate, WaitFor, Free außerhalb des Threads.

Waitfor nicht nötig da im Thread Destructor schon vorhanden!

jaenicke 21. Mai 2014 15:11

AW: TEvent.free im Thread Destructor?
 
Zitat:

Zitat von Mavarik (Beitrag 1259644)
Waitfor nicht nötig da im Thread Destructor schon vorhanden!

Wenn man es denn in der Reihenfolge aufruft wie Sir Rufo geschrieben hat, funktioniert das auch, ja.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:47 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz