AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Frage zu einer Type-Deklaration in TThread-Unit
Thema durchsuchen
Ansicht
Themen-Optionen

Frage zu einer Type-Deklaration in TThread-Unit

Ein Thema von Mackhack · begonnen am 6. Sep 2006 · letzter Beitrag vom 6. Sep 2006
Antwort Antwort
Benutzerbild von Mackhack
Mackhack

Registriert seit: 29. Nov 2003
Ort: San Diego, CA/USA
1.446 Beiträge
 
Delphi 2006 Architect
 
#1

Frage zu einer Type-Deklaration in TThread-Unit

  Alt 6. Sep 2006, 06:08
Hi,

kann mir mal jemand diese Zeile erklaeren als Typen-Name oder Deklaration in einer TThread-Unit:

Delphi-Quellcode:
Type
  TDirChangeEvent = Procedure(Sender: TObject; Const aChangedFile : String) Of Object;
Danke!
Um etwas Neues zu schaffen muss man seine Ohren vor den Nein-sagern verschliessen um seinen Geist öffnen zu können.
(George Lukas)
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Frage zu einer Type-Deklaration in TThread-Unit

  Alt 6. Sep 2006, 06:45
Hi,

es handelt sich um einen Methodenzeiger. Das heißt du kannst TDirChangeEvent als Variable deklarieren, der du eine Methode gleicher Signatur zu weisen kannst.
Ein typisches Beispiel wie man damit arbeitet kennst du sicherlich, denn die Ereignisse in Delphi basieren auf genau diesen Methodenzeigern. Allerdings legt hier der OI (wenn du es nicht per Hand machst) automatisch die entsprechende Methode an und weißt die zu.
Es gibt auch noch Funktionszeiger (ohne of Object). Einem Methodenzeiger musst du halt eine Methode (Prozedur oder Funktion eines Objekts) einem Funktionszeiger eine Funktion (die direkt in einer Unit liegt, ohne Klasse) zuweisen.

Soviel zur Theorie, es folgt die Praxis:

Delphi-Quellcode:
Type
  TDirChangeEvent = Procedure(Sender: TObject; Const aChangedFile : String) Of Object;

  TDeineThreadKlasse = class(TObject)
    public
      dirChangeEvent = TDirChangeEvent; // natürlich schöner mit Properties!
  end;

  TDeineEreignisbehandlungsKlasse = class(TObject)
    public
      procedure OnDirChange(Sender : TObject; const aChangedFile : String);
  end;
So, jetzt siehst du hier, dass TDeineThreadKlasse eine Variable von diesem Typ hat. Das heißt, dirChageEvent kann auf eine solche Methode zeigen. TDeineEreignisbehandlungsklasse besitzt eine Mehtode mit passender Signatur, du kannst diese jetzt direkt zuweisen:
Delphi-Quellcode:
var thread : TDeineThreadKlasse;
    event : TDeineEreignisbehandlungsKlasse;
begin
  // anlegen der instanzen
  ...
  thread.dirChangeEvent := event.OnDirChange;
end;
Tritt jetzt ein Ereignis in TDeineThreadKlasse auf, so schaut diese Klasse ob dirChangeEvent zugewiesen wurde (Adresse <> nil). Ist dies der Fall, wird die Methode (auf die diese Variable zeigt) aufgerufen
Delphi-Quellcode:
procedure TDeineThreadKlasse.DirChanged;
begin
  if assigned(self.DirChangeEvent) then
  begin
     self.DirChangeEvent(self, <Geändertes File>);
  end;
end;
Das selbe geschieht zum Beispiel auch, wenn du auf andere Events in Delphi reagieren möchtest (OnMouseMove, OnMouseDown, OnKeyUp, ...)

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Benutzerbild von Mackhack
Mackhack

Registriert seit: 29. Nov 2003
Ort: San Diego, CA/USA
1.446 Beiträge
 
Delphi 2006 Architect
 
#3

Re: Frage zu einer Type-Deklaration in TThread-Unit

  Alt 6. Sep 2006, 08:08
Hi,

dank dir. Ja ich arbeite mit dem Code auch und er funktioniert auch nur wusste ich einfach nicht was und wie genau. Das Problem war nur dass ich eben verstehen wollte warum mein Code funktioniert und was er genau macht.

Hoffe dass es keine dumme Frage war.
Um etwas Neues zu schaffen muss man seine Ohren vor den Nein-sagern verschliessen um seinen Geist öffnen zu können.
(George Lukas)
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Frage zu einer Type-Deklaration in TThread-Unit

  Alt 6. Sep 2006, 08:20
Zitat von Mackhack:
Hoffe dass es keine dumme Frage war.
Keineswegs. Ich bin zwar nicht der Meinung dass es gar keine dummen Fragen gibt, aber diese hier gehört definitiv nicht zu den Dummen. Ich denke jeder stolpert früher oder später mal über ein sehr spezielles Sprachkonstrukt.
Dass deine Frage nicht dumm ist sieht man allein daran, dass du fragst um zu verstehen!
  Mit Zitat antworten Zitat
Benutzerbild von Mackhack
Mackhack

Registriert seit: 29. Nov 2003
Ort: San Diego, CA/USA
1.446 Beiträge
 
Delphi 2006 Architect
 
#5

Re: Frage zu einer Type-Deklaration in TThread-Unit

  Alt 6. Sep 2006, 13:55
Hi,

dank dir. Haette doch noch eine Frage dazu:

Warum (da ich die Deklaration von jemandem bekommen habe als Tip sozusagen) warum wurden gerade die Argumente Sender: TObject und Const aChangedFile : String hierbei genommen?

Den Thread nutze ich um ein Verzeichnis zu ueberwachen mit Files die ich in einer Liste habe. Wurde eine File aus der Liste veraendert wird diese Datei in ein Destination-Directory kopiert.
Um etwas Neues zu schaffen muss man seine Ohren vor den Nein-sagern verschliessen um seinen Geist öffnen zu können.
(George Lukas)
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#6

Re: Frage zu einer Type-Deklaration in TThread-Unit

  Alt 6. Sep 2006, 14:36
Werde ich dir gerne erklären (ich hoffe dir machen längere Beiträge nichts aus).
An sich ist es die Idee so einfach. Du möchtest ein Ereignis haben. Dies kannst du z.B. mit einer solchen Implementierung (Methodenzeiger) erreichen. Dabei handelt es sich um einen so genannten Callback, da du eine übergebene Funktion aufrufst. Woher die Methode aber kommt, die da aufgerufen wird, dass weißt du / dein Thread gar nicht.
Die Frage ist nun also, sollte der das Wissen? Man versucht diese Frage immer mit nein zu beantworten. Das Prinzip dahinter nennt sich Abstraktion und bietet ein Menge vorteile. Da dein Thread keine Details des Besitzers dieser Callback-Methode hat, kann der Thread auch nicht auf solche zurückgreifen. Klingt noch nicht nach einem Vorteil? Ohne Detailkenntnis können keine Details beim Aufruf des Callbacks vorrausgesetzt werden, der Aufrufer ist also vollkommen austauschbar!
Irgendwie macht es aber keinen Sinn, wenn jmd. erfährt dass irgendein Ereignis eingetreten ist. Sagen wir du hast eine Klasse A, die die Callback-Methode für deinen Thread bereit stellt. Würde hier nur eine Methode aufgerufen werden (ohne Argumente), dann wüßte sie nur, irgendwo ist irgendwas passiert. Das hilft nicht weit. Überwacht sie nur den einen Thread, dann ist ihr sicherlich klar wer der Auslöser war. Der Thread könnte die Änderung ja auch intern speichern und als Property nach aussen führen, aber dann müsste A jetzt Detailwissen über die Properties haben und die neuen Werte abholen (bevor diese sich wieder ändern).
Dadurch, dass du diese als Argument übergibst und der Aufruf der Methode synchron erfolgt (es wird gewartet bis die Methode abgearbeitet ist), stellst du sicher, dass A (oder wer auch immer Besitzer des Callbacks ist) von jeder Änderung erfährt. Die Argumente sollten also immer die Information enthalten, was sich geändert hat (in diesem Fall durch aChangedFile gegeben).
Das mit dem Sender hat eigentlich die gleichen Gründe. Du möchtest alles so abstrakt wie möglich halten. Dass A eine Methode hat, die als Callback verwendet werden kann ist soweit klar. Aber wer sollte A daran hindern dies bei 2 oder mehr Threads zu tun? Sender teilt dann mit, wer das Ereignis ausgelöst hat, damit kannst du dann weiter arbeiten.
Ein etwas dummes Beispiel (da es leichter anders geht) wäre folgendes: Du baust dir eine Gruppe von Buttons, von denen nur einer gedrückt sein darf (also richtig runter). Natürlich würdest du normalerweise TSpeedButton einsetzen und den GroupIndex anpassen, aber die gibt es nicht und du entscheidest dich für Panel.
Ein Panel ist dabei der Träger der Buttons. Dieses Panel spielt keine Rolle, es gruppiert nur die anderen Panel, so dass du leichter über diese iterieren kannst. Wenn also von allen Paneln gesprochen wird, so meine ich alle Panel, die als Button auf diesem Gruppierungselement liegen.
Ja, wenn jetzt ein Panel gedrückt wird, dann muss es unten bleiben. Alle anderen Panel müssen hingegen rausgedrückt werden. Du siehst, dass dies eine sehr allgemeine Formulierung ist. Würdest du für jeden Druck auf ein Panel eine eigene Methode schreiben, könnte das etwas anstrengend (und Fehleranfällig bei Copy&Paste) werden. Viel schöner wäre es, wenn du eine Methode hast, die erstmal alle Panel rausdrückt und dann nur das angeklickte Panel runterdrückt. Mit Sender hast du genau die Möglichkeit. Hier steht dann halt drin, wer das Ereignis auslöste.
Sender wird allgemein immer als TObject übergeben, um auch hier keine Einschränkungen zu machen. Damit kann ein Sender ein vollkommen beliebiges Objekt sein. Wie und wo man das ausnutzt merkt man immer in der Praxis, weitere Beispiele meinerseits wären wohl so schlecht konstruiert wie das ebend.

Ich hoffe, dass dir damit soweit klar ist, warum man diese Argumente übergibt. Dein Empfänger kann so feststellen was passiert ist (Art des Ereignis + Parameter) und wer das Ereignis auslöste.

Trotz alle dem ist es nicht gerade die schönste Lösung. Es gibt im Moment mind. zwei Beiträge, die näher auf das Thema Observer-Pattern eingehen. Ich rate jedem dazu, diesem den Vorzug vor Methodenzeigern zu geben. An sich ist es kein direkter Ausschluss, auch das Observer-Pattern kann mit Methodenzeigern verwendet werden. Genaueres findest du in den Beiträgen.
Die eigentliche Idee beim Observer ist eigentlich nur, dass sich interessenten An- und Abmelden können. Während du mit einem Methodenzeiger häufig nur einem Objekt ermöglichst über ein Ereignis informiert zu werden, ermöglicht ein Observable es mehrere (oder auch keine) Observer zu informieren.
  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 15:38 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