![]() |
Re: Liste Thread sicher abholen
Hi scp,
reicht es wenn ich Initialize und Delete im Create und Destroy aufrufe? Oder muss ich das jedesmal vor und nach Zugriff auf die Liste des Threads machen? Gruß oki Nachtrag: Auch wenn die Frage blöd erscheint, kommt das in meinen Thread oder in meine Hauptanwendung? |
Re: Liste Thread sicher abholen
Nein, die beiden rufst du nur einmal auf.
Wenn du dir mal die Implementation von TThreadList anschaust, wirst du auch feststellen, dass es nur eine TList mit einer Critical Section ist - es ist also nichts dabei, wenn du dir analog eine TThreadStringList schreibst. Zu schade, dass Delphi noch keine Generics kennt. |
Re: Liste Thread sicher abholen
Danke für den Tipp. Ich schau mir das in TThreadList an und erweitere meine Listen oder meinen Thread (wenn ich durchsehe). So langsam kommt aber Licht ins dunkel. Ich lass den Thread erst mal offen und poste später mein Ergebnis.
Gruß oki |
Re: Liste Thread sicher abholen
OK, ich hab mir das jetzt mal mit der ThreadList angesehen. Sah schlimmer aus als es ist. Ich hab noch nicht den kompletten Code, aber der Rahmen steht. Hier mein Ergebnis:
Delphi-Quellcode:
Wenn ihr der Meinung seid das ist so ok, dann hab ich's begriffen und kann die Thread als beantwortet setzen. :lol:
type
TTShutDownThread = class(TThread) private FLock: TRTLCriticalSection; FShutDownList : TShutDownList; // Schließliste FWindowList : TWindowList; // Liste der aktiven Fenster function GetWinParamObj(index: Integer): TWinParamClass; function GetShutDownObj(index: Integer): TWinParamClass; protected procedure Execute; override; procedure Lock; procedure UnLock; procedure UpdateWindowList; // Fensterliste aktualisieren public constructor Create(CreateSuspended: Boolean); reintroduce; virtual; Destructor Destroy; override; Procedure GetWindowList(const AList : TWindowList); end; implementation { TTShutDownThread } constructor TTShutDownThread.Create(CreateSuspended: Boolean); begin inherited; InitializeCriticalSection(FLock); FWindowList := TWindowList.Create; FShutDownList := TShutDownList.Create; end; destructor TTShutDownThread.Destroy; begin Lock; try FreeAndNil(FWindowList); FreeAndNil(FShutDownList); inherited Destroy; finally Unlock; DeleteCriticalSection(FLock); end; end; procedure TTShutDownThread.Execute; begin // hier die Behandlung der Listen mit vorherigen Lock und abschleißendem Unlock end; procedure TTShutDownThread.GetWindowList(const AList: TWindowList); begin Lock; // Liste kopieren Unlock; end; procedure TTShutDownThread.Lock; begin EnterCriticalSection(FLock); end; procedure TTShutDownThread.UnLock; begin LeaveCriticalSection(FLock); end; Dank und Gruß oki |
Re: Liste Thread sicher abholen
Ein paar Kleinigkeiten fallen auf: Gib CreateSuspended im Konstruktor einfach weiter an Inherited, das macht es schon richtig, und spar dir damit auch die letzten beiden Zeilen, die so ziemlich falsch sind.
In GetWindowList sollte der Parameter const sein, da du ja nur ein Assign ausführst, aber keine neue Instanz zuweist. Dein Destruktor sieht etwas seltsam aus, sollte aber funktionieren. |
Re: Liste Thread sicher abholen
Hi,
das mit dem CreateSuspend habe ich mit Absicht so gemacht. Aber du hast wohl recht. Execute wird erst aufgerufen wenn der Constructor abgearbeitet wird. Da hab ich schief gedacht. Das mit dem const nehme ich ohne Kommentar hin. Bezüglich des Destructors habe ich mich an den Aufbau aus TThreadList gehalten. Ich hätte selber das inherited ans Ende gesetzt. So dachte ich mir, die haben sich vielleicht was dabei gedacht und es mir nur nicht mitgeteilt. Der Original Destructor der TThreadList sieht so aus:
Delphi-Quellcode:
Ich werd jetzt mal den letzten Code editieren un deine Bemerkungen einarbeiten.
destructor TThreadList.Destroy;
begin LockList; // Make sure nobody else is inside the list. try FList.Free; inherited Destroy; finally UnlockList; DeleteCriticalSection(FLock); end; end; Gruß oki |
Re: Liste Thread sicher abholen
Hi,
warum machst du eigentlich nicht 2 Listen. 1x private und 1x public. Und immer zwischendurch mit Synchronize eine Kopie von der private Liste auf die public Liste. Das sollte doch von der Umsetzung/Handling schneller gehen. Die CriticalSections sind durchaus interessant, aber wenn es mal schnell gehen muß, dann vielleicht doch die 5-Minuten-Ter.... :) Oder bin ich da jetzt "heavy on the woodway" ? Ich weiß das oki den synchronize nicht benutzen wollte, weil er die Anwendung nicht informieren möchte, aber tut er hier ja auch nicht :wink: cu Oliver |
Re: Liste Thread sicher abholen
Moin Sir Rofu,
die Idee hört sich auch erst mal nicht schlecht an. Da ich mit dem Thema Threadsicheres arbeiten noch nicht so tief befreundet bin hab ich hier aber noch ne Menge Unsicherheiten. Imho syncronisiert Synchonize ja die Ausführung einer Procedure über einen anderen Thread. Also am Beispiel eines Ereignisses sieht das bei mir immer so aus:
Delphi-Quellcode:
Mit dem Proceduraufruf DoUpdate wird also der Code des Threads, der eine Ereignisbehandlung für OnUpdate zur Verfügung stellt mit durchlaufen. Die Rückkehr erfolgt dann in die Execute-Methode des Thread.procedure TMyThread.Execute; begin .... Synchronize(DoUpdate); .... end; procedure TMyThread.DoUpdate; begin if Assignd(FOnUpdate) then FOnUpdate(self); // hier mal ein eigenes NotifyEvent end; Bei der von dir vorgesellten Variante würde der Zugriff auf die TempList (ich nenne jetzt mal die Übergabeliste so) nicht im Rahmen des Synchronize erfolgen. Es kommt mir so vor, dass mein MainThread dann eingentlich wieder nicht sicher zugreift. Eben nur auf die TempList. Das Problem scheint also nur verschoben zu sein. Das sind jetzt aber nur meine Überlegungen zu dieser Variante. Kein Wissen!!! Was mir zusätzlich nicht gefällt ist das führen eines Duplikates der Liste. Ich bin mir sicher, dass das nicht stört, aber mann hällt alle Daten ständig doppelt. Dabei bekomme ich immer einen blöden Geschmack im Mund. Wenn es vom Aufwand vertretbar ist, dann vermeide ich das lieber. Im Moment halte ich die Idee mit CritcalSection sogar für sehr elegant. Ich implementiere das einmal in meinem Thread mit zugegeben minimalem Codeaufwand und kann eigentlich alle zukünftigen Zugriffe auf alle Eigneschaften meines Threads sicher implementieren. Ich werd heute im laufe des Tages die Klasse weiter fertig stellen und von meinen Erfahrungen an dieser Stelle berichten. Danke für deinen Beitrag, vielleicht kann noch jemand anderes etwas Licht in das Thema bringen, liebe Grüße oki |
Re: Liste Thread sicher abholen
Oh Backe, da läuft mächtig was schief. So geht es nicht. Folgendes Problem:
Mein Thread läuft sauber und ordentlich und arbeitet seine Execute-Methode ab.
Delphi-Quellcode:
Ok, sieht ja mal simpel und somit gut aus.
procedure TShutDownThread.Execute;
begin while not Terminated do begin Lock; try FWindowList.EnumTopLevelWindows; // interne liste aktualisieren Sleep(Interval); // warte mal die eingestellte Zeit, nicht so 'ne Hektik (prefered 200) finally Unlock; end; end; end; Jetzt meine Public-Methode des Threads zum Abholen der Werte der Liste.
Delphi-Quellcode:
AssignList habe ich an dieser Stelle zusätzlich implementiert. Ist auch logisch und kein Hit. Sollte jemand damit Sorgen haben poste ich den Code.
procedure TShutDownThread.GetWindowList(const AList: TWindowList);
var WinParamObj: TWinParamClass; begin if not Assigned(AList) then Exit; Lock; try AList.AssignList(FWindowList); finally UnLock; end; end; Nun passiert folgendes. Rufe ich in meinem Programm diese Methode auf
Delphi-Quellcode:
steht die Anwendung.
procedure TForm1.RefreshWindowList;
var WindowList: TWindowList; begin if assigned(FShutDownThread) then begin WindowList := TWindowList.Create; try FShutDownThread.GetWindowList(WindowList); ........ Ich habe mit dem Debugger die entsprechende Stelle gefunden. Es ist der Aufruf Lock in der Thread-Methode GetWindowList. Lock implementiert hier
Delphi-Quellcode:
Genau aus EnterCriticalSection kehrt die Procedur nicht zurück.
procedure TShutDownThread.Lock;
begin EnterCriticalSection(FLock); end; Da läuft doch was schief in meiner Logik. ich denke mal ich habe das was entscheidendes in der Handhabung der CriticalSection nicht verstanden oder bringe was in der Abarbeitung des Threads furcheinander. Das ist doch nur ein Verständnis und Handlingproblem meinerseits? Wenn mir da mal einer auf die Sprünge helfen kann, währe toll. Gruß oki |
Re: Liste Thread sicher abholen
Nimm mal das sleep in der Execute Methode aus dem try-Finally-Block bzw. aus dem Lock-Unlock-Block heraus.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:51 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 by Thomas Breitkreuz