Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Liste Thread sicher abholen (https://www.delphipraxis.net/115283-liste-thread-sicher-abholen.html)

oki 9. Jun 2008 19:03


Liste Thread sicher abholen
 
Hi Leute!

ich bin mir bei meinem aktuellen Thema nicht ganz sicher wie ich es angehen soll. Folgende Voraussetzung:
Ich habe eine eigene Klasse mit dem Vorfahren TThread. Diese Klasse besitzt eine Public-Eigenschaft WindowList vom Typ TStringList. Der Thread aktualisiert diese Liste fortlaufend in seiner Execute-Methode.
Nun möchte ich mit meiner Anwendung den Inhalt der Liste abholen. Ich habe den Verdacht, dass das so einfach nicht geht wenn ich die Liste öffentlich mache und dann durch die Items iteriere um alles auszulesen. Mein Thread könnte da ja was in der Zwischenzeit ändern. Ein Ereignis mittels Synchronize will ich aber auch nicht aus dem Thread losschicken, da es nicht nötig ist die Anwendung zu informieren.

Hier mal der Code zur Klassendeklaration:

Delphi-Quellcode:
type
  TShutDownThread = class(TThread)
  private
    FWindowList : TWindowList;                               // Liste der aktiven Fenster
    FShutDownList : TShutDownList;                           // Schließliste
    function GetWinParamObj(index: Integer): TWinParamClass;
    function GetShutDownObj(index: Integer): TWinParamClass;
  protected
    procedure Execute; override;
    procedure UpdateWindowList;                              // Fensterliste aktualisieren
  public
    constructor Create(CreateSuspended: Boolean); reintroduce; virtual;

    property ShutDownList : TShutDownList read FShutDownList;
    property ShutDownObj [index : Integer] : TWinParamClass read GetShutDownObj;
    property WindowList : TWindowList read FWindowList;
    property WinParamObj [index : Integer] : TWinParamClass read GetWinParamObj;
  end;
Ich glaube, dass sollte Ärger geben:
Delphi-Quellcode:
  For Counter := 0 to ShutDownThread.WindowList.Count - 1 do begin
    Obj := ShutDownThread.WindowList.Objects[Counter];
    ... und dann lesen wir schön aus und zeigen an
  end;
Sorry, hab grad versehentlich den absenden Button gedrückt. Hier noch schnell der Rest.

Ich dächte, dass geht in die Hose. Die Frage ist nun, wie sollte ich die Items threadsicher aus dem Thread holen?

Gruß oki

[edit] nach Hinweis von sirius Fehler im Code gefixt! [/edit]

Apollonius 9. Jun 2008 19:09

Re: Liste Thread sicher abholen
 
Ja, das funktioniert nicht. Das beste ist, wenn du eine Critical Section einführst, die immer beim Bearbeiten der Liste betreten wird. Beim Auslesen solltest du die Section betreten, den Inhalt an eine neue Liste assignen und die Section verlassen und danach mit der neuen Liste weiterarbeiten, damit der Thread nicht zu lang aufgehalten wird.
Interessant könnten für dich auch einfach verkettete Listen sein, da man diese ganz ohne Critical Sections threadsicher bearbeiten kann - es werden nur die Interlocked-Funktionen benötigt.

oki 9. Jun 2008 19:17

Re: Liste Thread sicher abholen
 
Hi,

das war zu schnell.

Das mit dem Assign hatte ich mir auch schon überlegt. Etwa so:
Delphi-Quellcode:
procedure TShutDownThread.AssignWindowList(AList : TWindowList);
begin
  AList.Assign(FWindowList);
end;
Das geht sicher schneller, aber ist genau so'n Blödsinn. Was meinst du mit Critical Section? Beim Eintritt in die Procedure den Thread anhalten (Suspent) und nach Assign Resume?

Gruß

sirius 9. Jun 2008 19:24

Re: Liste Thread sicher abholen
 
Oben redest du von der FWindowList und in deinem Beispiel ist es Shutdownlist :gruebel:

Je nach Inhalt der Liste, wäre vielleicht eine TThreadList etwas für dich.

Apollonius 9. Jun 2008 19:24

Re: Liste Thread sicher abholen
 
Nein, ich meine eine Critical Section :wink: - das ist ein Objekt, dass von Windows zur Verfügung gestellt wird, in der Unit SyncObjs befindet sich eine Kapselung. Die Funktionsweise ist einfach: Wenn du eine Critical Section betreten willst, die schon ein anderer Thread besitzt, fällt der Thread in einen Wartezustand, der erst aufgehoben wird, wenn der Thread im Besitz der Critical Section sie genau so oft verlassen wir betreten hat (die Aufrufe können also durchaus gestapelt werden). Damit kannst du also kritische Abschnitte wie das Assign und das Bearbeiten der Liste schützen.

oki 9. Jun 2008 19:28

Re: Liste Thread sicher abholen
 
@sirius: Danke fur den Hinweis. Es soll natürlich die TWindowList sein. :oops: Blöder Fehler. Ich korrigiere das gleich.

@Apoll....: Da muss ich mal kurz die Hilfe bemühen. Scheint echt ne Bildungslücke bei mir zu sein. Melde mich wenn der Nebel weg ist.

Gruß oki

oki 9. Jun 2008 19:45

Re: Liste Thread sicher abholen
 
Hi sirius noch mal.

Ich stell mich im moment etwas schwerfällig an, aber was hilfts. Mir ist gerad nicht so richtig klar wie ich die ThreadList werwenden soll. Vieleicht denk ich auch zu kompliziert.

Einfach gedacht wurde ich es so machen.

Mein Thread ist ok, meine TWindowList ist ein Nachkomme von TThreadList und immer wenn ich die Einträge auslesen will mache ich folgendes:
Delphi-Quellcode:
procedure TShutDownThread.AssignWindowList(AList : TWindowList);
begin
  FWindowList.LockList;
  AList.Assign(FWindowList);
  FWindowList.UnlockList;
end;
@Apoll...:
Das mit dem Critical Section hört sich irgentwie gewaltig an. Macht sicher Eindruck und ist ein prodessioneller Weg, sieht aber im Moment so aus, als ob das umfangreicher wird als das was ich eigentlich nur machen will. Bis jetzt hab ich nur Einträge aus dm MSDN gefunden, und das sah nicht wie so eben mal schnell gemacht aus. Ich forsch da aber mal weiter. Dem Hinweis mit der Unit SyncObjs muß ich noch nachgehen.

gruß oki

sirius 9. Jun 2008 20:01

Re: Liste Thread sicher abholen
 
Ja, das ist soweit ok, wenn du auch das Einfügen mit TThreadList.add machst.
mit Locklist bekommst du übrigens auch direkt einen Zeiger auf die Liste darunter.

Kommt auch alles darauf an, was du für Sachen in der Liste hast. Denn ein Assign kopiert ja erstmal nur die Zeiger und nicht dessn Inhalt.

scp 9. Jun 2008 20:07

Re: Liste Thread sicher abholen
 
Critival Sections sind nicht kompliziert. Du brauchst nur eine Variable und vier Funktionen:

Delphi-Quellcode:
var
  mySection: RTL_CRITICAL_SECTION;
Einmalig rufst du folgendes auf:
Delphi-Quellcode:
InitializeCriticalSection(mySection);
Den Zugriff auf die Liste machst du in diesem Konstrukt:
Delphi-Quellcode:
EnterCriticalSection(mySection);
try
  //....
finally
  LeaveCriticalSection(mySection);
end;
Und zum Abschluss folgt dies:
Delphi-Quellcode:
DeleteCriticalSection(mySection);

oki 9. Jun 2008 20:08

Re: Liste Thread sicher abholen
 
Klar, ich hatte mir natürlich gedacht, dass ich im Execute ein LockList ausführe wenn ich die Liste bearbeite und ein UnlockList, wenn ich fertig bin. Das mit dem Assign-Beispiel war jetzt nur der Einfachheit halber.

Das blöde ist, dass meine WindowList eine StringList ist. Ich hatte mir aber schon gedacht die WindowList und die ShutDownList als ListItems in die ThreadList zu legen.

Gruß oki


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:24 Uhr.
Seite 1 von 5  1 23     Letzte »    

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