Einzelnen Beitrag anzeigen

tgoessi

Registriert seit: 31. Mai 2005
34 Beiträge
 
Delphi 5 Enterprise
 
#5

Re: Interfaceliste bei einem Auto-Objekt

  Alt 7. Jun 2005, 14:05
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.
  Mit Zitat antworten Zitat