Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Überschreiben von TThread.Terminate (https://www.delphipraxis.net/152790-ueberschreiben-von-tthread-terminate.html)

MatthiasR 7. Jul 2010 07:31

Delphi-Version: 2005

Überschreiben von TThread.Terminate
 
Ich stehe gerade vor folgendem "Problem". Ein wirkliches Problem ist es nicht, da ich Alternativen habe, es zu umgehen, trotzdem würde ich gerne wissen, warum mein erster Ansatz so nicht funktioniert.

Ich habe eine eigene Thread-Klasse geschrieben, die (logischerweise) von TThread abgeleitet ist. Ich möchte gerne die Methode TThread.Terminate aus dem public-Bereich überschreiben, weil bei deren Aufruf intern in meiner eigenen Thread-Klasse noch etwas mehr passieren soll, als nur das FTerminated-Feld auf True zu setzen. Aber auch das soll natürlich weiterhin passieren. Daher habe ich TThread.Terminate folgendermaßen überschrieben:
Delphi-Quellcode:
interface

type
  TMeinThread = class(TThread)
  private
    ...
  public
    procedure Terminate; // override hier ja nicht nötig, da nicht virtual
  end;

implementation

procedure TMeinThread.Terminate;
begin
  // TThread.Terminate aufrufen, um FTerminated auf True zu setzen
  inherited;

  // anschließend noch alles weitere machen
  ...
end;

end.
Das Problem ist, dass TThread.Terminate scheinbar übersprungen wird und von dem inherited nicht aufgerufen. Ein Breakpoint innerhalb von TThread.Terminate wird grün dargestellt und deshalb beim Debuggen auch nie erreicht. Woran liegt das? Kann man TThread.Terminate nicht überschreiben und falls nicht, warum?

Danke für die Aufklärung :)

Stevie 7. Jul 2010 07:36

AW: Überschreiben von TThread.Terminate
 
Die Antwort hast du schon selber gegeben durch deinen Kommentar hinter Terminate.
Wenn intern Terminate aufgerufen wird, dann wird das TThread.Terminate aufgerufen und nicht TMeinThread.Terminate.
Dazu müsste die Methode in TThread schon virtual sein.

himitsu 7. Jul 2010 07:37

AW: Überschreiben von TThread.Terminate
 
Delphi-Quellcode:
// override hier ja nicht nötig, da nicht virtual
Genau falsch ... es muß heißen
"override hier ja nicht möglich, da nicht virtual"

Heißt also, du kannst es nicht überschreiben
Und TThread ruft nur das ihm bekannte Terminate auf (deines kennt er nicht).

Wie wäre es mit einem Eventhandler für OnTerminate?

sirius 7. Jul 2010 07:45

AW: Überschreiben von TThread.Terminate
 
Zitat:

Zitat von himitsu (Beitrag 1033915)
Delphi-Quellcode:
// override hier ja nicht nötig, da nicht virtual
Genau falsch ... es muß heißen
"override hier ja nicht möglich, da nicht virtual"

Heißt also, du kannst es nicht überschreiben
Und TThread ruft nur das ihm bekannte Terminate auf (deines kennt er nicht).

Ganz richtig wäre: TThread ruft Terminate nie auf, deswegen muss es auch nicht virtual sein. Ein simples verdecken (reintroduce) reicht hier völlig aus.

Virtuelle Methoden sind ja nur wichtig, wenn von deiner Elternklasse in eine deiner Methoden gesprungen werden soll. Aber Terminate ruft man ja nur von außen auf, deswegen einfach verdecken, fertsch.

Stevie 7. Jul 2010 07:49

AW: Überschreiben von TThread.Terminate
 
Zitat:

Zitat von sirius (Beitrag 1033919)
Ganz richtig wäre: TThread ruft Terminate nie auf, deswegen muss es auch nicht virtual sein. Ein simples verdecken (reintroduce) reicht hier völlig aus.

Schonmal in den Destructor von TThread geguckt?

MatthiasR 7. Jul 2010 07:49

AW: Überschreiben von TThread.Terminate
 
Zitat:

Zitat von himitsu (Beitrag 1033915)
Delphi-Quellcode:
// override hier ja nicht nötig, da nicht virtual
Genau falsch ... es muß heißen
"override hier ja nicht möglich, da nicht virtual"

Ob du's glaubst oder nicht, ich habe relativ lange überlegt, ob ich "nötig" oder "möglich" schreiben soll, ersteres kam mir aber in meinem Zusammenhang sinnvoller vor.
Zitat:

Zitat von himitsu (Beitrag 1033915)
Heißt also, du kannst es nicht überschreiben
Und TThread ruft nur das ihm bekannte Terminate auf (deines kennt er nicht).

Heißt also, ich habe keine Möglichkeit, innerhalb von TMeinThread.Terminate das TThread.Terminate aufzurufen? Ist das allgemein bei jeder nicht-virtuellen Methode so, wenn man in einer abgeleiteten Klasse eine Methode genauso benennt? Ab da kennt die abgeleitete Klasse die geerbte Methode gleichen Namens nicht mehr?
Zitat:

Zitat von himitsu (Beitrag 1033915)
Wie wäre es mit einem Eventhandler für OnTerminate?

Jo, das wäre eine der Alternativen, die mir im Kopf rumschwebt :) . Wobei ich dann ja nicht verhindern kann, dass jemand, der meine neue TMeinThread-Klasse verwendet, dem OnTerminate-Ereignis einen anderen Handler zuordnet und meiner dadurch abgehängt wird?

mkinzler 7. Jul 2010 07:53

AW: Überschreiben von TThread.Terminate
 
Wenn nich virtuell dann gibt es auch keine VMT

sirius 7. Jul 2010 08:07

AW: Überschreiben von TThread.Terminate
 
Zitat:

Zitat von Stevie (Beitrag 1033922)
Zitat:

Zitat von sirius (Beitrag 1033919)
Ganz richtig wäre: TThread ruft Terminate nie auf, deswegen muss es auch nicht virtual sein. Ein simples verdecken (reintroduce) reicht hier völlig aus.

Schonmal in den Destructor von TThread geguckt?

Ui, korrekterweise wäre dann ein Virtual sinnvoll, weil man sich sonst nirgendwo ins Terminate reinklinken kann.
Aber ein kurzes Üüberlegen, wann der Fall eintritt, sagt mir, dass man dann den Thread während des Betriebes von außen abschießen muss. Böse Sache, dass.

jfheins 7. Jul 2010 08:09

AW: Überschreiben von TThread.Terminate
 
Zitat:

Zitat von sirius (Beitrag 1033919)
Ganz richtig wäre: TThread ruft Terminate nie auf, deswegen muss es auch nicht virtual sein. Ein simples verdecken (reintroduce) reicht hier völlig aus.

Virtuelle Methoden sind ja nur wichtig, wenn von deiner Elternklasse in eine deiner Methoden gesprungen werden soll. Aber Terminate ruft man ja nur von außen auf, deswegen einfach verdecken, fertsch.

Wette ich um ein virtuelles Bier dagegen ;)

Wenn man "von Außen" eine TThread Variable hat, und diese dann aber mit einem TmeinThread belegt und .terminate aufruft, wird trotzdem nur TThread.Terminate aufgerufen.

MatthiasR 7. Jul 2010 08:14

AW: Überschreiben von TThread.Terminate
 
Andere Frage: wieso kann ich in TThread.Terminate auf der (einzigen) Zeile
Delphi-Quellcode:
FTerminated := True;
keinen Breakpoint setzen, der auch angesteuert wird?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 Uhr.
Seite 1 von 3  1 23      

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