Autor Beitrag
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Fr 08.12.06 00:22 
Hallo!

Ich begebe mich gerade in .NET-Gefilde. Als kleine Testanwendung hatte ich mir eine kleine DirectX-App gedacht.

Um nun einzelne Objekte freizugeben (wie man das ja so gewohnt ist, in .NET muss man ja dank der GC nicht mehr so genau hinschauen mit den Objekten) habe ich den Destruktor meines Hauptformulars übersteuert, so sieht er aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
destructor TWinForm.Destroy;
begin
  MessageBox.Show('HALT!');
  FDevice.Free;
  inherited;
end;


Solange es sich um das Hauptformular handelt, das freigegeben wird, reagiert der Destruktor gar nicht. Erstelle ich aber über das Hauptformular eine Instanz derselben Klasse TWinform und gebe diese frei, erscheint die Meldung. Ist das normal in .NET, daß die Sachen, sobald die Applikation an sich nun beendet wird, nicht mehr über den regulären Weg weggeräumt werden?
:gruebel:

Cu,
Udontknow
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Fr 08.12.06 00:30 
Unter .Net gibt es keinen Destruktor, dafür einen Garbage Collector.

_________________
Markus Kinzler.
Udontknow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Fr 08.12.06 00:34 
Nun, ich kann es kompilieren, und der Destruktor wird ja auch manchmal aufgerufen, also gibt es schon noch Destruktoren. :)
Was, wenn ich im Destruktor nicht aufräumen möchte sondern noch irgendeine andere Sache ausführen möchte?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Fr 08.12.06 00:44 
Du hast doch wahrscheinlich dieses "Delphi Reference.pdf"-Dingens. Da steht was drin, was Delphi aus einem Destruktor in .NET macht. Zu finden unter "Delphi -> Speicherverwaltung -> Speicherverwaltung auf der .NET Plattform -> Das Dispose-Muster".

Ich finde es etwas ungünstig, dass Borland versucht, .NET wie Win32 aussehen zu lassen. Einer der Gründe, warum ich Delphi nicht für .NET benutze.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 08.12.06 00:56 
Nimm doch einfach Dispose. Aufrufe von Dispose (durch den Garbage Collector) werden zwar an den Destruktor weitergeleitet, aber das kann man sich genausogut sparen, wenn man direkt Dispose benutzt.
Wann aber Dispose aufgerufen wird, weißt du nicht!! Dies (also das Aufrufen von Finalize, was jede .NET Klasse hat) macht der GC irgendwann. Deshalb bringt es auch nix, da Meldungen auszugeben, ich nehme an, die siehst du nur nicht ;-). Denn eigentlich sollte Destroy schon immer aufgerufen werden. Ist aber eben nicht dazu da, dort (Meldungs-)Fenster anzuzeigen.
In Dispose wird aber auch ggf. ein Meldungsfenster angezeigt.

Ach so: So gut kenne ich .NET auch noch nicht ;-), muss also nicht unbedingt genau stimmen... Aber so in etwa ists...
Udontknow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Fr 08.12.06 01:19 
Danke erstmal für die Hinweise, damit bin ich schon sehr viel weiter gekommen!

Der Destruktor wird laut Delphi-Hilfe nur aufgerufen, wenn explizit von irgendwo Objekt.Free aufgerufen wurde. Das ist eben beim Hauptformular nicht der Fall, siehe DPR-Quellcode:
ausblenden Delphi-Quelltext
1:
2:
3:
begin
  Application.Run(TWinform.Create);
end.


Macht man daraus folgendes, ist das Verhalten wie gewünscht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
begin
  WF:=TWinform.Create;
  try
    Application.Run(WF);
  finally
    WF.Free;
  end;
end.


Tja, Pustekuchen mit Nicht-mehr-so-genau-auf-die-Freigabe-von-Objekten-achten-müssen! :)

Dispose ist übrigens eine fiese Sache, das läuft u.U. in einem anderen Thread... :shock:

Cu,
Udontknow
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 08.12.06 01:26 
user profile iconUdontknow hat folgendes geschrieben:
Tja, Pustekuchen mit Nicht-mehr-so-genau-auf-die-Freigabe-von-Objekten-achten-müssen! :)

Dispose ist übrigens eine fiese Sache, das läuft u.U. in einem anderen Thread... :shock:

Ja, in dem vom GC nehme ich an. Aber da Dispose auch nicht dazu gedacht ist, auf andere Teile der Anwendung zuzugreifen ist das ja auch kein Problem.
Naja, bis jetzt hat zum Glück alles so funktioniert wie ich es wollte, wenn ich mal was mit .NET gemacht habe. Aber mal sehen, wie das bei größeren Projekten wird (die ich aber in absehbarer Zeit nicht portieren werde).