![]() |
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:
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, ....
type
TInput = class(TPersistent) private Daten : string; InpThread : TInputThread; protected public constructor Create; destructor Destroy; override; published end; Der Thread schaut im Moment mal so aus:
Delphi-Quellcode:
Nun frage ich mich aber ... Wie kann ich vom Thread die Daten zur Klasse bekommen? Kann man da eine Art Notifikation absetzen?
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; 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? |
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.
|
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. |
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 |
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; |
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. |
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
|
Re: Daten vom Thread zur Klasse zur Anwendung
Zitat:
|
Re: Daten vom Thread zur Klasse zur Anwendung
Moin !
Zitat:
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: ![]() Nur leider kann man an Klassen ja keine Messages schicken. |
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 19:57 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