AGB  ·  Datenschutz  ·  Impressum  







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

Anonymous method: TProc Referenzen vergleichen

Ein Thema von Rollo62 · begonnen am 6. Sep 2018 · letzter Beitrag vom 8. Sep 2018
Antwort Antwort
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Anonymous method: TProc Referenzen vergleichen

  Alt 6. Sep 2018, 14:50
Habe mal einen kleinen test gebaut:

Delphi-Quellcode:
unit testProc;
interface
uses
   System.Sysutils,
   DUnitX.TestFramework;
type
   [TestFixture]
   TestTproc = class(TObject)
   private
      function GetProc(const Value : integer): TProc;
   public
     [TEST]
     procedure test2vars;
     [TEST]
     procedure test2refernce;
   end;

implementation

{ TestTproc }
type
 PIInterface = ^IInterface;

function TestTproc.GetProc(const Value : integer): TProc;
begin
   result :=
      procedure
      Var x : integer;
      begin
       x := 2 * Value;
       if x > 3 then;
      end;
end;

procedure TestTproc.test2vars;
var lp1, lp2 : Tproc;
    obj1, obj2: TInterfacedObject;

begin
 lp1 := GetProc(1);
 lp2 := GetProc(1);
 assert.AreNotEqual<Tproc>(lp1, lp2);
 obj1 := PIInterface(@lp1)^ as TInterfacedObject;
 obj2 := PIInterface(@lp2)^ as TInterfacedObject;
 // Will fail....
 assert.AreEqual<TInterfacedObject>(obj1, obj2);

end;

procedure TestTproc.test2refernce;
var lp1, lp2 : Tproc;
    obj1, obj2: TInterfacedObject;

begin
 lp1 := GetProc(1);
 lp2 := lp1;
 assert.AreEqual<Tproc>(lp1, lp2);
 obj1 := PIInterface(@lp1)^ as TInterfacedObject;
 obj2 := PIInterface(@lp2)^ as TInterfacedObject;
 assert.AreEqual<TInterfacedObject>(obj1, obj2);
end;


initialization
TDUnitX.RegisterTestFixture(TestTproc);
end.
Da sieht man schön das test2refernce funktioniert.
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.379 Beiträge
 
Delphi 12 Athens
 
#2

AW: Anonymous method: TProc Referenzen vergleichen

  Alt 6. Sep 2018, 18:26
Die Zeiger kannst du vergleichen, daber wenn du jedes Mal eine neue anonyme Methode genierierst, dann haben die Alle auch immer einen unterschiedlichen Zeiger.

Also zwei TProc lassen sich problemlos vergleichen, aber nur wenn du am Anfang auch einmal aus deiner Procedure eine TProc machst. (siehe Post #2, nur die Variable halt globaler speichern)


TProc ist intern ein Interface, aber leider wird das Objekt dazu dynamisch gebaut, also Anhand des zugewiesenen Prozedur/Methoden-Typen hat das Objekt unterschiedlichen Speicher und da dafür auch keine RTTI generiert wird, kann man den Inhalt leider nicht auslesen, da man nicht weiß was man da eigentlich liest (Methode/ClassMethode, StaticMethode/ReguläreProcedur oder sone eingebettete Anonyme ... den Speicher zu analysieren macht keinen Spaß und ist auch nicht 100% sicher).
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 6. Sep 2018 um 18:34 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.175 Beiträge
 
Delphi 12 Athens
 
#3

AW: Anonymous method: TProc Referenzen vergleichen

  Alt 7. Sep 2018, 06:21
Zitat:
aber wenn du jedes Mal eine neue anonyme Methode genierierst,
@himitsu
Dankesehr für den Hinweis.
Genau das war mir eben nicht ganz klar, ob der Kompiler das bei jedem Aufruf neu anlegt.
Bei genauerer Überlegung muss er das aber eingenlich machen, denn es könnte ja ein Tread o.ä. diese Eintrittfunktion mehrfach aufrufen.

Das interpretiere ich mal so, das dann alle Funktionen jeweils ihren eigenen Scope haben müssen.

Dann dürfte sich auch nichts ändern wenn man in der Eintrittsfunktion "const" verwendet ?
Delphi-Quellcode:
procedure TAnonCaller.ExecuteWithKillAndDelay([B]const [/B]AProc : TProc);
begin
...
Weil trotzdem jeder Aufruf der Eintrittsfunktion einen neuen Scope erzeugen muss, richtig ?

Schade, dann muss ich mir da irgendwas drumrum bauen.

Edit:
Ich habe es übrigens bisher so gemacht das mir die Eintrittfunktion eine eindeutige ID zurückliefert.
Diese muss ich dan ausserhalb der TAnonCaller Klasser verwalten, das hätte ich aber gerne von innen gemacht.

Rollo

Geändert von Rollo62 ( 7. Sep 2018 um 06:31 Uhr)
  Mit Zitat antworten Zitat
hoika

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

AW: Anonymous method: TProc Referenzen vergleichen

  Alt 7. Sep 2018, 07:51
Hallo,
geht es hier jetzt speziell um anonyme Funktionen oder eher um den asynchronen Aufruf, also um Thread-Synchronisation?

Wenn Du wirklich die Methode killen willst, würde ich einen Thread benutzen,
wenn es um die Verhinderung des doppelten Aufrufes geht, dann mit Hilfe der Synchronisations-Objekte, z.B. TCriticalSection.
Heiko
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.175 Beiträge
 
Delphi 12 Athens
 
#5

AW: Anonymous method: TProc Referenzen vergleichen

  Alt 7. Sep 2018, 08:58
Es geht eher um die anonymen Methoden.

Die TAnonCaller macht gewisse Dinge intern, die ich bei einem vorzeitigen zweiten Aufruf abbrechen möchte.

Da hilft mir ein Thread nicht unbedingt weiter, denn mir fehlt ja die Referenz auf den Caller,
das ist mein Problem damit.

Denn ohne diese Referenz kann ich nicht eindeutig sagen "welchen" Caller ich abbrechen soll,
und diese Referenzen scheinen ja bei jedem Aufruf intern neu angelegt zu werden.

Eine Möglichkeit wäre vielleicht dem Caller einfach den Sender mitzugeben, und diesen dann intern mitzuverwalten
(was ich zwar nicht so ideal finde, aber womöglich gar nicht anders geht).

Delphi-Quellcode:
procedure TAnonCaller.ExecuteWithKillAndDelay(Sender : TObject; AProc : TProc);
begin
...
Rollo
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.379 Beiträge
 
Delphi 12 Athens
 
#6

AW: Anonymous method: TProc Referenzen vergleichen

  Alt 8. Sep 2018, 09:45
Genau das war mir eben nicht ganz klar, ob der Kompiler das bei jedem Aufruf neu anlegt.
Bei genauerer Überlegung muss er das aber eingenlich machen, denn es könnte ja ein Tread o.ä. diese Eintrittfunktion mehrfach aufrufen.

Das interpretiere ich mal so, das dann alle Funktionen jeweils ihren eigenen Scope haben müssen.
Jupp, das Const spielt nur mit der Referenzzählung des internen Interfaces, aber an dem übergebenem Wert ändert es nichts.

Und bedenke auch, dass hier diese Methode auch auf lokale Variablen zugreifen könnte, das ist noch ein Grund, warum das bei jedem Aufruf neu sein muß.


Wie gesagt, man könnte zwar in Ausnahmefällen prüfen ob die internen Zeiger gleich sind, aber hier würde auch der Scope z.B. auf lokale Variablen sich sowieso unterscheiden, selbst wenn die Code-Adresse der Methode gleich wäre.

Da sich die Position des Methoden-Zeigers innherhalb des internen InterfacesObjekts nicht fest ist, lässt dieses sich halt schwer vergleichen.
Ein Therapeut entspricht 1024 Gigapeut.
  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:17 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-2025 by Thomas Breitkreuz