Hallo
Hier etwas Code:
Delphi-Quellcode:
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;
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:
Delphi-Quellcode:
procedure TDisp.New_EventData(State, NumColls : byte);
begin
FLastState := State;
FLastNumColls := NumColls
FEvents.OnNewData(State, NumColls);
end;
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.
Die Routine dafür:
Delphi-Quellcode:
procedure TDisp.TriggerData;
begin
FEvents.OnNewData(FLastState,FLastNumColls);
end;
Wenn der Server ein Event auslöst, geschieht das in einer Schleife:
Delphi-Quellcode:
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;
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.
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 von
Bernhard Geyer:
Zitat von
tgoessi:
Genauso hab ich es gemacht.
Glaube ich nicht ganz. Ich hab sowas vor einigen Jahren gemacht und hatte keine Probleme mit Referenzzählung.
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
Entwickler-Forum nachfragen, denn dort ist A. Kosch aktiv.