Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Objekte in der richtigen Reihenfolge freigeben (https://www.delphipraxis.net/160262-objekte-der-richtigen-reihenfolge-freigeben.html)

Rainer Wolff 5. Mai 2011 09:16

Delphi-Version: 2006

Objekte in der richtigen Reihenfolge freigeben
 
Hallo,

ich verwende in meinem Projekt ein Modul zum Meldungen mitloggen. Dieses Logging ist als Singleton implementiert, der beim ersten Zugriff initialisiert wird.
Freigegeben wird die Klasse im finalization-Abschnitt, und da liegt gerade mein Problem: Die Klasse wird freigegeben, danach wird in einer anderen Unit noch eine Log-Meldung ausgegeben und es kommt zur Zugriffsverletzung.

Wie löst ihr so ein Problem? Soweit ich mich informiert habe, legt der Compiler die Reihenfolge der finalization fest, so dass ich darauf nur eingeschränkt Einfluss habe.
Das Singleton als Interface einbauen und somit die Speicherverwaltung an Delphi abdrücken?
Alle Meldungen, die nach der finalization kommen, ignorieren (nicht so gut)?
Oder was gibt es sonst für Möglichkeiten?

Gruß Rainer

SirThornberry 5. Mai 2011 09:23

AW: Objekte in der richtigen Reihenfolge freigeben
 
Du könntest im finalization die Instanz auf nil setzen und in deiner Logfunktion prüfen ob die Instanz <> nil ist.

himitsu 5. Mai 2011 09:57

AW: Objekte in der richtigen Reihenfolge freigeben
 
Zitat:

Zitat von Rainer Wolff (Beitrag 1098965)
Soweit ich mich informiert habe, legt der Compiler die Reihenfolge der finalization fest, so dass ich darauf nur eingeschränkt Einfluss habe.

Alle Units, welche im Interface-Abschnitt eingebunden sind werden immer vor "initialization" der eigenen Unit initialisiert und nach "finalization" finalisiert.

Wenn du eine Unit im Implementation-Abschitt einbindest, dann kann diese Unit eventuell erst nach "initialization" initialisiert, bzw. vor "finalization" finalisiert werden
und man sollte daher dort nicht (ohne Prüfung) auf globale Objekte zugreifen.


Also indirekt hast du schon etwas Einfluß, auf die Reihenfolge.

Rainer Wolff 5. Mai 2011 10:01

AW: Objekte in der richtigen Reihenfolge freigeben
 
Zitat:

Zitat von SirThornberry (Beitrag 1098967)
Du könntest im finalization die Instanz auf nil setzen und in deiner Logfunktion prüfen ob die Instanz <> nil ist.

Hab ich temporär so schon implementiert, aber: Dann ist zwar die Zugriffsverletzung weg, aber es werden halt auch keine Meldungen mehr geloggt.

@Himitsu: Innerhalb einer einzelnen Unit wäre das Problem wohl so zu lösen, aber die Logfunktion ist ja so breit über viele verschiedene Units gestreut, dass die Kontrolle auf diesem Weg schwierig wird.

himitsu 5. Mai 2011 10:13

AW: Objekte in der richtigen Reihenfolge freigeben
 
Zitat:

Zitat von Rainer Wolff (Beitrag 1098976)
Zitat:

Zitat von SirThornberry (Beitrag 1098967)
Du könntest im finalization die Instanz auf nil setzen und in deiner Logfunktion prüfen ob die Instanz <> nil ist.

Hab ich temporär so schon implementiert, aber: Dann ist zwar die Zugriffsverletzung weg, aber es werden halt auch keine Meldungen mehr geloggt.

Tja, wenn das Logging-Objekt freigegeben ist, dann kann man natürlich nix mehr loggen. :angle2:

Als eine Alternative bliebe noch eine statisch eingebundene DLL, in welcher das Logging abläuft.
Diese DLL wird auf jedenfall erst nach allen deinen Unis entladen.

Oder du machst es so, daß, sobald das Logging schon freigegeben wurde, dieses nochmal kurz erstellt, der Eintrag eingetragen und dann gleich wieder freigegeben wird.

stahli 5. Mai 2011 10:25

AW: Objekte in der richtigen Reihenfolge freigeben
 
Zitat:

Zitat von himitsu (Beitrag 1098974)
Alle Units, welche im Interface-Abschnitt eingebunden sind werden immer vor "initialization" der eigenen Unit initialisiert und nach "finalization" finalisiert.

Ich denke, die Aussage stimmt LEIDER nicht. Ich habe das hier schon einmal nachgefragt.
Dass alternative Lösungen möglich sind ist schon klar, aber die Initialisierungsreihenfolge von Units kann man m.E. nicht erzwingen.

Klaus01 5. Mai 2011 10:47

AW: Objekte in der richtigen Reihenfolge freigeben
 
Hallo,

vielleich kannst Du das Singleton auch so aufbauen:

Delphi-Quellcode:
 TLogger = class(TObject)
    private
      messageList : TThreadStringList;
      constructor create;
    public
      destructor Destroy; override;
      procedure push(s: AnsiString);
      function pop:AnsiString;
      function stackCount : Word;
      class function getInstance:TLogger;
  end;

implementation


var
  singleInstanceLogger : TLogger;


constructor TLogger.create;
begin
  inherited create;
  messageList := TThreadStringList.create;
end;

destructor TLogger.Destroy;
begin
  freeAndNil(MessageList);
  inherited destroy;
end;

class function TLogger.getInstance:TLogger;
begin
  if singleInstanceLogger = nil then
    singleInstanceLogger := Tlogger.create;

  result := singleInstanceLogger;
end;
Edit: Es vielleicht etwas zu kurz gegriffen, denn wenn zwischen dem destroy und der Ausgabe von Meldungen
kein getInstance mehr aufgerufen wird, knallt es auch hier...


Grüße
Klaus

Rainer Wolff 5. Mai 2011 11:14

AW: Objekte in der richtigen Reihenfolge freigeben
 
@Klaus: Vielleicht stehe ich noch auf der Leitung, aber:
Wo und wodurch wird dein Singleton denn wieder freigegeben, denn die Freigabe ist ja mein Problem.

Rainer

Klaus01 5. Mai 2011 11:26

AW: Objekte in der richtigen Reihenfolge freigeben
 
..freigeben kann man es mit freeAndNil(LoggerInstance) oder LoggerInstance.free.

Aber wie ich im Nachtrag meines Beitrages bereits gesagt habe, greift das zu kurz.

Oder du müsstes vor jeder LogMeldung loggerInstance := TLogger.getInstance aufrufen,
dann wird gegebenenfalls eine Instanz erzeugt oder die bereits bestehende übergeben.

Freigeben kannst Du sie dann in jedem finalization Abschnitt einer jeden Unit.
Oder in dem finalization Abschnitt der letzten Unit.


Zitat:

Finalization sections are executed in the opposite order from initialization sections. For example, if your application initializes units A, B, and C, in that order, it will finalize them in the order C, B, and A.
Quelle: Hilfe aus TurboDelphi

Grüße
Klaus


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:18 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