Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Daten vom Thread zur Klasse zur Anwendung (https://www.delphipraxis.net/149293-daten-vom-thread-zur-klasse-zur-anwendung.html)

moelski 18. Mär 2010 08:50


Daten vom Thread zur Klasse zur Anwendung
 
Moin !

Ich versuche mich gerade an etwas Theorie zum Thema Threads, Klassen und Notifikationen. Und dabei bin ich auf ein paar Dinge gestoßen wo ich im Moment nicht weiter komme.

Zu meiner Idee ...
Nehmen wir an wir wollen eine Anwendung erstellen die von mehreren Eingangsquellen Daten aufnehmen kann. Und gehen wir mal weiter davon aus das ein Eingang ein TCP Socket ist und ein Eingang z.B. eine CSV Datei.
Um das ganze möglichst universell zu halten ist meine Idee nun, die Eingänge jeweils in eine Klasse zu packen. Wir erstellen also zwei Klassen die in etwa so aussehen könnten:
Delphi-Quellcode:
type
  TInput = class(TPersistent)
    private
      Daten    : string;
      InpThread : TInputThread;
    protected

    public
      constructor Create;
      destructor Destroy; override;
    published

  end;
InpThread ist an dieser Stelle nur ein "Platzhalter" der mittels Thread Daten liefern kann. Hier könnte letztlich alles mögliche stehen. Sei es ein TCP Server, eine serielle Schnittstelle, ein Thread der eine CSV auswertet, ....

Der Thread schaut im Moment mal so aus:
Delphi-Quellcode:
type
  TInputThread = CLASS(TThread)
    private
      Daten : string;
    protected
      procedure execute; override;
    public
      constructor create; virtual;
  end;

procedure TInputThread.execute;
begin
//  while not Terminated do;
  Daten := 'test';
end;

constructor TInputThread.create;
begin
  inherited create(true); // CreateSuspended = true
  freeOnTerminate := true;
end;
Nun frage ich mich aber ... Wie kann ich vom Thread die Daten zur Klasse bekommen? Kann man da eine Art Notifikation absetzen?
Und wie kann ich dann aus der Klasse eine Notifikation in Richtung Anwendung schicken um zu signalisieren das neue Daten zur Bearbeitung zur Verfügung stehen?

Hat da jemand eine gute Idee zu?

ghost007 18. Mär 2010 09:01

Re: Daten vom Thread zur Klasse zur Anwendung
 
Naja, du musst das "Ereginis" im Prinzip zur Hauptanwendung durchreichen. Egtl. musst du dir nur eine Procedure baun, die als Notification fungiert und dann darauf reagieren. Verstehe dein Problem jetzt nicht so ganz. Ich würde dem Thread eine variable geben, in die du beim erstellen des Threads die Notify Procedure übergibst. Die kann der Thread dann aufrufen und das Hauptprogramm weiß bescheid.

moelski 18. Mär 2010 09:09

Re: Daten vom Thread zur Klasse zur Anwendung
 
Moin !

Mein Thread ist aber Bestandteil der Klasse.
Wie kommen dann die Daten vom Thread zur Klasse? Der Thread selber "kennt" die Klasse ja gar nicht.

ghost007 18. Mär 2010 09:35

Re: Daten vom Thread zur Klasse zur Anwendung
 
Hey,
wie schon gesagt, ich würde dem Thread eine Variable geben, in der du eine Procedure speicherst. Die Procedure wird dann vom Thread aufgerufen, wenn er Daten loswerden will. Die Procedure selber liebt im Hauptprogramm. Natürlich musst du diese Procedure in einer CritialSection aufrufen, da du sonst Probleme mit inkonsistenten Daten bekommen kannst.

//Edit: Natürlich kann die besagte Procedure auch einfach nur in der Klasse liegen, anstatt im Hauptprogramm

Blup 18. Mär 2010 09:44

Re: Daten vom Thread zur Klasse zur Anwendung
 
Delphi-Quellcode:
interface

uses
  Classes;

type
  TInputMethode = procedure(AValue: string) of object;

  TInputThread = class(TThread)
  private
    FDaten : string;
    FOnInput: TInputMethode;
  protected
    procedure DoOnInput;
    procedure Execute; override;
  public
    constructor create; virtual;
    property OnInput: TInputMethode read FOnInput write FOnInput;
  end;

  TInput = class(TPersistent)
  private
    FDaten    : string;
    FInpThread : TInputThread;
  protected
    procedure DoInput(AValue: string);
  public
    constructor Create;
    destructor Destroy; override;
  published
  end;

implementation

{ TInputThread }

procedure TInputThread.DoOnInput;
begin
  if Assigned(FOnInput) then
    FOnInput(FDaten);
end;

procedure TInputThread.execute;
begin
//  while not Terminated do;
  FDaten := 'test';
  Synchronize(DoOnInput);
end;

constructor TInputThread.create;
begin
  inherited create(true); // CreateSuspended = true
  // problematisch da TInput eine Zeiger auf den Thread besitzt
  // freeOnTerminate := true;
  freeOnTerminate := False;
end;

{ TInput }

constructor TInput.Create;
begin
  inherited;
  FInpThread := TInputThread.Create;
  FInpThread.OnInput := DoInput;
  FInpThread.Resume;
end;

destructor TInput.Destroy;
begin
  FInpThread.Free;
  inherited;
end;

procedure TInput.DoInput(AValue: string);
begin
  FDaten := AValue;
  {...}
end;

ghost007 18. Mär 2010 10:00

Re: Daten vom Thread zur Klasse zur Anwendung
 
Hi Blup,
bist du dir sicher, dass der Synchronize call auf die DoOnInput, den Zugriff auf die Property FDaten thread-safe macht?
Ich glaub nämlich nicht. So wie ich das verstanden habe, bewirkt synchronize ja nur, dass die Procedure nur sequentiell aufgerufen werden kann. Das schützt die Variable aber nicht vor Änderungen.

guinnes 18. Mär 2010 10:28

Re: Daten vom Thread zur Klasse zur Anwendung
 
Syncronize läuft im Hauptthread und da der NebenThread darauf wartet, das Syncronize abgearbeitet wird, kann er die Daten nicht ändern

ghost007 18. Mär 2010 10:32

Re: Daten vom Thread zur Klasse zur Anwendung
 
Zitat:

Zitat von guinnes
Syncronize läuft im Hauptthread und da der NebenThread darauf wartet, das Syncronize abgearbeitet wird, kann er die Daten nicht ändern

Hm, dann hab ich das wohl mit java verwechselt... dachte das Synchronize bezieht sich nur auf die jeweilige Klasse.

moelski 18. Mär 2010 10:32

Re: Daten vom Thread zur Klasse zur Anwendung
 
Moin !

Zitat:

Syncronize läuft im Hauptthread
Genau das stellt aber ein Problem dar. Wenn nämlich der Hauptthread (das wäre im aktuellen Fall ja die Anwendung selber) hängt, dann würde es auch den ganzen Rest blocken und es würde mitunter sogar zum Datenverlust führen.

Gibt es nicht evtl. eine Variante um ganz auf Synchronize zu verzichten?
Derzeit nutzen wir Windows Messages um den Thread von der Anwendung zu entkoppeln und die Daten zu übergeben.
So wie es auch hier beschrieben wird: http://edn.embarcadero.com/article/22411

Nur leider kann man an Klassen ja keine Messages schicken.

ghost007 18. Mär 2010 10:37

Re: Daten vom Thread zur Klasse zur Anwendung
 
Naja, zum übergeben der Daten MUSST du in irgend einer Form synchronisieren. Entweder über das besagte Synchronize oder eine CriticalSection.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:59 Uhr.
Seite 1 von 2  1 2      

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