![]() |
AW: CriticalSection und Threads
Kann mir einer mal ein Beispiel nennen, wo ein Konstruktor knallen kann, weil 'er noch nicht fertig ist'?
Wenn ich schreibe:
Delphi-Quellcode:
Hat Foo erst dann einen Wert, wenn der Konstruktor fertig ist.
Foo := TMyThread.Create;
Da es eine Grundregel gibt, die besagt, das Konstruktoren keinen logischen Code beinhalten sollen, kann ich mir irgendwelche komplex konstruierten Gebilde sparen, wo ich vielleicht doch auf ein Objekt zugreife, dessen Konstruktor noch nicht abgearbeitet ist, z.B.:
Delphi-Quellcode:
So, dagegen kann man sich also absichern, ja? Wozu? Sowas macht man einfach nicht:
Constructor TMyThread.Create (aSomeObject : TSomeObject);
Begin ... aSomeObject.CallMe(Self); ... End; Procedure TSomeObject.CallMe (aThread : TMyThread); Begin aThread.Bang(); End;
Delphi-Quellcode:
Der Verwender des TMyThread muss eben Initialize() aufrufen. Und das kann er erst, wenn die Instanz (vollständig) instantiiert wurde.
Constructor TMyThread.Create (aSomeObject : TSomeObject);
Begin ... FSomeObject := aSomeObject; ... End; Procedure TMyThread.Initialize(); Begin FSomeObject.CallMe(Self); End; Procedure TSomeObject.CallMe (aThread : TMyThread); Begin aThread.Bang(); End; Ich bleib dabei: Diese Gedankenspiele sind nett, aber lenken vom eigentlichen Problem ab. Sofern man das Gedankenspiel nicht als solches auffässt. Wie wäre es mit Überlegungen, die Endlosschleifen erkennen?
Delphi-Quellcode:
Obwohl ich ein System kenne, das versucht, soetwas zu erkennen (so ein Schwachsinn).
While True do;
|
AW: CriticalSection und Threads
Zitat:
Allerdings: Der oben beschriebene Ansatz löst dieses Problem, wie ich oben schon geschrieben habe, gerade *nicht*. Und ein paar andere Fälle löst er auch nicht. Im Grunde genommen gebe ich dir also damit recht, dass die CS im Konstruktor nichts bringt. mfg Christian |
AW: CriticalSection und Threads
Zitat:
![]() Jedes Objekt "enthält" ab Delphi 2009 ein "Lock", das wie eine Critical Section benutzt werden kann (und noch mehr kann wie z.B. PulseAll und Wait) - und es verfällt automatisch mit Ablauf der Objekt-Lebenszeit. Dass Threads von außen nach ihrem Start aufgerufen werden erscheint mir ansonsten auch etwas ungewöhnlich - in welchem Status der Thread gerade ist, wenn man eine seiner Operationen aufruft, ist unbestimmt. |
AW: CriticalSection und Threads
Zitat:
Der Schutz des Konstruktors wird dann wichtig, wenn man z.B. eine Klasse erzeugt, die z.B. einen Thread-Pool erstellt und diesem Thread-Pool auch sich selbst als Referenz mitgibt. Hiermal als völlig ungeschützte Klasse:
Delphi-Quellcode:
Mit meiner Lösung bekomme ich die Klasse 100% Thread-Safe mit relativ geringem Aufwand.
TMyThreadPool = class
private _Pool : TList<TPoolThread>; public constructor Create( PoolSize : integer ); // Some Properties ... end; constructor TMyThreadPool.Create; begin inherited Create; _Pool := TObjectList<TPoolThread>.Create; while _Pool.Count < PoolSize do _Pool.Add( TPoolThread.Create( Self ) ); // Init Some Properties end; Eine Ableitung von der Klasse TMyThreadPool geht auch sehr charmant und bleibt 100% Thread-Safe |
AW: CriticalSection und Threads
Man könnte hier natürlich darüber streiten, ob die Pool-Threads den Pool überhaupt kennen sollten, aber hier hast du recht. Immer, wenn man im Konstruktor einen Thread erzeugt und dem Self mitgibt hat man das Problem und deine Lösung hilft hier. OK, verstanden.
mfg Christian |
AW: CriticalSection und Threads
Ich bleibe dabei: Trenne Instantiierung von Initialisierung und man hat viel mehr Zeit für andere Sachen. Weil man sich nicht mit solchem "Quark" beschäftigen muss. Wobei das Problem an sich schon recht interessant ist.
|
AW: CriticalSection und Threads
Zitat:
mfg Christian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz