![]() |
Interfaceliste bei einem Auto-Objekt
Hallo
Bei einem TAutoObject mit ciMultiInstance wird bei jedem Zugriff von einem externen Prozess ein neues Interface erzeugt. Wie kann ich eine Referenzliste auf alle diese erzeugten Interfaces erhalten? :| Es geht darum vom Serverprozess eine Meldung an alle vorhandenen Interfaces zu senden. Die erzeugten Interfaces in einer TInterfaceList zu speichern funktioniert nicht richtig, da zusätzliche Referenzen erzeugt werden, was zur Folge hat, dass das Objekt nicht mehr freigegeben wird, wenn alle externen Proesse, die darauf zugreifen beendet werden. :? Wie kann man das am besten lösen? Tom |
Re: Interfaceliste bei einem Auto-Objekt
Das Schlagwort für Events vom Server zum Client ist
![]() Dazu holst Du dir auf jedenfall mal das ![]() ![]() |
Re: Interfaceliste bei einem Auto-Objekt
Genauso hab ich es gemacht.
Ich speichere die self-Pointer in der initialize-Methode in einer Interfaceliste. Das funktioniert soweit ok. Ich kann dadurch auch Methoden übers Interface auslösen und alle Clients benachrichtigen. Nur bei der Freigabe gibts ein Problem. Wenn ich den self-Pointer in der Interfaceliste speichere wird der Referenz-Counter erhöht. Die Destroy-Routine (welche den Pointer in der Interfaceliste wieder freigibt) wird deshalb beim Beenden eines Clients nicht aufgerufen. Das muss ich irgendwie anders lösen aber wie? Tom Zitat:
|
Re: Interfaceliste bei einem Auto-Objekt
Zitat:
Ich denke mal du machst hier einige Fehler und hälst dich nicht an das "Kochrezept" von A. Kosch. Kannst Du auch etwas relevanten Code posten. Evtl. auch im ![]() |
Re: Interfaceliste bei einem Auto-Objekt
Hallo
Hier etwas Code:
Delphi-Quellcode:
Das IDispTriggerEvents ist ein privates Interface von TDisp bzw. IDisp. Damit greift der Server auf eine Interfaceroutine zu, welche das Event auslöst. Diese Routine sieht folgendermassen aus:
Var DispInterfaces : TInterfaceList; //als globale Variable, da der Serverprozess auf die Interfaces zugreifen muss
procedure TDisp.Initialize; begin inherited Initialize; FConnectionPoints := TConnectionPoints.Create(Self); // für die Events if AutoFactory.EventTypeInfo <> nil then FConnectionPoint := FConnectionPoints.CreateConnectionPoint( AutoFactory.EventIID, ckSingle, EventConnect) else FConnectionPoint := nil; if not assigned (DispenserInterfaces) then DispenserInterfaces := TInterfaceList.Create; DispenserInterfaces.Add(self as IDispTriggerEvents); inc(IntfRefCount); // Zähler für Clients end; destructor TDisp.Destroy; var i : byte; begin if assigned (DispenserInterfaces) then DispenserInterfaces.Remove(self as IDispTriggerEvents); dec(IntfRefCount); if IntfRefCount = 0 then begin DispenserInterfaces.Free; end; inherited Destroy; end;
Delphi-Quellcode:
Der Grund für dies: Jeder Client kann die Daten des letzten Events abrufen, was seinerseits ein neues Event auslöst, das dann aber nur an diesen Client geschickt wird.
procedure TDisp.New_EventData(State, NumColls : byte);
begin FLastState := State; FLastNumColls := NumColls FEvents.OnNewData(State, NumColls); end; Die Routine dafür:
Delphi-Quellcode:
Wenn der Server ein Event auslöst, geschieht das in einer Schleife:
procedure TDisp.TriggerData;
begin FEvents.OnNewData(FLastState,FLastNumColls); end;
Delphi-Quellcode:
Man könnte nun natürlich die Variable DispInterfaces auch als interne Variable im TDisp-Objekt speichern und in der Routine New_EventData die Schleife machen.
procedure TServer.FireEvent;
var i : byte; begin for i := 0 to DispInterfaces.Count-1 do (DispInterfaces.Item[i] as IDispTriggerEvents).New_EventData(FState,FColls); end; Doch auch wenn man DispInterfaces objektintern speichert, geht der Referenzzähler beim Beenden eines Clients nicht auf 0 und die Destroy-Routine wird nicht aufgerufen. Gruss Tom Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:01 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