AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Auf 'Parent Object' zugreifen

Ein Thema von Julian M. · begonnen am 5. Feb 2019 · letzter Beitrag vom 6. Feb 2019
Antwort Antwort
Julian M.

Registriert seit: 28. Dez 2010
41 Beiträge
 
#1

Auf 'Parent Object' zugreifen

  Alt 5. Feb 2019, 21:12
Delphi-Version: 5
Hallo,

wahrscheinlich stell ich mich mal wieder zu dusslig an aber,
wie greife ich auf das 'Parent Object' zu?

Also der Hintergrund ist,
sagen wir ich habe ein Objekt der Klasse TFileExplorer. Dieses Objekt beinhaltet wiederum Objekte der Klassen TFileStringList und TFindFileThread.

Der FindFileThread, welcher die Dateiliste erstellt soll diese nun in die FileStringList schreiben.

Meine Lösung wäre nun, dem Thread beim Start das aufrufende Objekt mitzugeben, also so:
Delphi-Quellcode:
  findFileThread.callinginstance := self;
  findFileThread.Start;

Und im Thread dann so auf die Stringlist zuzugreifen:
TFileExplorer(callinginstance).FileStringList := FindAllFiles;
Ist es so korrekt wie ich es machen würde oder gibt es eine Lösung ohne dem Thread das aufrufende Objekt mitzugeben?

Cheers,
Julian
  Mit Zitat antworten Zitat
Julian M.

Registriert seit: 28. Dez 2010
41 Beiträge
 
#2

AW: Auf 'Parent Object' zugreifen

  Alt 6. Feb 2019, 02:11
Also erstmal hatte ich vergessen zu erwähnen dass es sich beim Thread um einen Thread der Klasse TThread handelt und ich Lazarus/Freepascal verwende.

Des Weiteren habe ich mir die Frage wohl schon selbst beantworten können.
Und zwar ist es denke ich eleganter, Objekte in einem eigenen constructor zu übergeben. zweitens braucht mein Thread ja nicht dessen Parent, sondern die Stringlist des Parent. Drittens eignet sich dafür ein Pointer

Delphi-Quellcode:

type
  TFileWalker = class(TThread)
  protected
    procedure Execute; override;

    private
    Ffilepath: string;
    FStringListPointer :^Tstringlist;
    Freceiverformhandle:HWND;
  public
    constructor Create(StringListpointer:Pointer:Pointer; filepath:String; receiverformhandle: HWND);
end;


constructor TFileExplorer.Create(StringListpointer:Pointer; filepath:String; receiverformhandle: HWND);
begin
  inherited create(true);
  FStringListPointer := StringListpointer;
  Ffilepath := filepath;
  Freceiverformhandle := receiverformhandle;
  self.Start;
end;

Geändert von Julian M. ( 6. Feb 2019 um 02:15 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
490 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Auf 'Parent Object' zugreifen

  Alt 6. Feb 2019, 08:43
Ich sehe eine Schwierigkeit: was, wenn der Thread länger braucht, als die übergebene TStringList lebt? Die KÖNNTE währenddessen zerstört worden sein. Meine Lösung wäre, dem Thread eine Callbackprozedur zu übergeben, die nach Beendigung im Mainthread ausgeführt wird. Darin wird dann die TStringList befüllt.
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Auf 'Parent Object' zugreifen

  Alt 6. Feb 2019, 09:15
Hallo,
fehlt da nicht auch noch der Hinweis auf Synchronize?
Es geht ja schon um den Oberflächen-Zugriff eines anderen Threads.
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
490 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Auf 'Parent Object' zugreifen

  Alt 6. Feb 2019, 09:29
Hatte ich vorausgesetzt, aber Du hast Recht - sollte erwähnt werden
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.464 Beiträge
 
Delphi 12 Athens
 
#6

AW: Auf 'Parent Object' zugreifen

  Alt 6. Feb 2019, 09:49
Ein Pointer auf eine Variable einer Instance von TStringList ist an sich schon wiedersinnig.
Es kann nicht sichergestellt werden, dass die Variable oder der Inhalt der Stringliste außerhalb verändert wird oder überhaupt noch gültig ist.
Mit einer Kopie der Stringliste zu arbeiten, erscheint mit sicherer.
Delphi-Quellcode:
type
  TFileWalker = class(TThread)
  protected
    procedure Execute; override;
  private
    FFilepath: string;
    FStringList: TStringList;
    FFreceiverFormHandle: HWND;
  public
    constructor Create(AStrings: TStrings; AFilepath: string; AReceiverFormHandle: HWND);
    destructor Destroy; override;
  end;


constructor TFileExplorer.Create(AStrings: TStrings; AFilepath: string; AReceiverFormHandle: HWND);
begin
  inherited Create(False);

  FStringList := TStringList.Create;
  FStringList.Assign(AStrings);

  FFilepath := AFilepath;
  FFReceiverFormHandle := AReceiverFormHandle;
end;

destructor TFileExplorer.Destroy;
begin
  FStringList.Free;

  inherited;
end;
"Start" ist nicht erforderlich, wenn man "CreateSuspended" auf False setzt.
Der Thread wird automatisch gestartet, wenn der Constructor beendet ist.
  Mit Zitat antworten Zitat
Julian M.

Registriert seit: 28. Dez 2010
41 Beiträge
 
#7

AW: Auf 'Parent Object' zugreifen

  Alt 6. Feb 2019, 13:12
Ich danke euch sehr für das Feedback! Wirklich toll, wie hier Probleme aufgezeigt werden.

Die StringList lebt so lange, bis sie durch erneuten Aufruf des FileExplorer (versehentlich habe ich einmal den Namen "FileWalker" hier eingeschleust)
neu created wird.

Die Gefahren des Multithreadings sind mir bewusst, da Freepascal leider keine anonymen Methoden unterstützt, ist mir die Nutzung von Synchronize eigentlich etwas zu aufwendig.
Als (zugegeben dürftige) Alternative nutze ich die Windows Messages.

Daher beim Erstellen des FileExplorer Threads auch die Übergabe der receiverformhandle: HWND
Der Thread ruft dann nach Befüllen der StringList den Befehl auf: SendMessage(Freceiverformhandle, 1125, 1, 0);

Delphi-Quellcode:
procedure TForm1.WndProc(var Msg: TMessage);
begin
  inherited;
  if Msg.Msg = 1125 then
    case msg.WParam of
      1: myInst.fillLvWithSl(); //Der FileExplorer Thread ist fertig, jetzt die Listview füllen.
    end;
end;

Jetzt ist mir leider noch nicht klar, warum die Nutzung eines Pointers für die StringList schlecht ist?
Klar kann ich auch eine Kopie der StringList übergeben, aber bedeutet das nicht mehr Rechenaufwand?
Es gibt nur diese eine Instanz der StringList die wie erwähnt ausschließlich durch den Thread erstellt und befüllt wird.
Danke für den Hinweis, dass Thread.Start nicht notwendig ist. Freue mich was zu lernen.


Liebe Grüße, Julian
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Auf 'Parent Object' zugreifen

  Alt 6. Feb 2019, 13:29
Hallo,
man benutzt halt Pointer nicht, basta

Nein, warum so kompliziert, zumal Objekte intern eh auch nur Pointer sind.

Bei manchen Datentypen, z.B. Arrays kann es passieren, dass ein SetLength den internen Pointer ändert,
weil der Memory-Manager einen anderer, größerer Speicher benutzt und den aktuellen Inhalt des Arrays dort reinkopiert.
Die Array-Variable und der Programmierer bekommen davon aber nichts mit.

Dann wäre der andere gesicherter Pointer futsch und der Zugriff sorgt für "etwas" Ärger...
Heiko
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:30 Uhr.
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