Form.ShowDialog () und dispose

8

Wenn ich eine Methode wie diese habe:

%Vor%

Muss ich weiterhin dispose im Formular aufrufen, obwohl es außerhalb des Gültigkeitsbereichs liegt, der für die Garbage Collection geeignet ist.

Bei einigen Tests, die Show () mehrfach aufrufen. Irgendwann scheint es, als ob der GC sie sammelt, da ich den Speicher-Spiking sehen kann, dann geht er irgendwann runter.

Von MSDN scheint es zu sagen, Sie müssen sich entsorgen, wenn das Formular nicht mehr benötigt wird.

    
pdiddy 12.07.2012, 14:39
quelle

6 Antworten

0

In Ihrem konkreten Beispiel, nein, ist es unwahrscheinlich, dass es besonders nützlich wäre. Formulare halten nicht viel Ressourcen, also wenn es etwas länger dauert, bis ein Teil des Codes aufgeräumt ist, wird das kein Problem verursachen. Wenn dieses Formular gerade ein Steuerelement enthält, mit dem beispielsweise ein Video abgespielt wird, dann hält es vielleicht eine beträchtliche Anzahl von Ressourcen fest, und wenn Sie diese Ressourcen tatsächlich in der Dispose-Methode entsorgen, lohnt es sich Nehmen Sie sich die Zeit zu rufen Sie entsorgen. Für 99% Ihrer Formulare ist die Dispose-Methode jedoch leer. Ob Sie sie aufrufen oder nicht, hat wahrscheinlich keine (oder keine spürbare) Auswirkung auf Ihr Programm.

Der Grund, warum es da ist, ist in erster Linie die Möglichkeit, in den 1% der Fälle, in denen es wichtig ist, Ressourcen zu entsorgen.

Es ist auch erwähnenswert, dass, wenn ein Form geschlossen ist, seine Methode Dispose bereits aufgerufen wird. Sie müssen nur dann einen using oder expliziten Dispose Aufruf hinzufügen, wenn Sie eine Forms-Ressource vor dem Schließen dieses Formulars entsorgen möchten. (Das klingt nach einer allgemein schlechten Idee für mich). Das ist leicht genug zu testen. Erstellen Sie einfach ein Projekt mit zwei Formen. Lassen Sie das zweite Formular einen Ereignishandler an das Disposing -Ereignis anhängen und ein Meldungsfeld oder etwas anzeigen. Wenn Sie dann eine Instanz dieses Formulars erstellen und es (als Dialog oder nicht) anzeigen, werden Sie sehen, dass das Meldungsfenster sofort angezeigt wird, wenn Sie es schließen, auch wenn Sie die Instanz "Formular" herum und ohne Sie behalten Sie müssen immer einen using oder Dispose -Aufruf hinzufügen.

    
Servy 12.07.2012, 15:08
quelle
10

Was passiert, wenn das Element nur verwaltete Ressourcen hat, ist das Aufrufen von dispise nicht unbedingt erforderlich , aber wird dringend empfohlen weil es zur Verfügung stellt deterministisch . Es ist nicht immer erforderlich (in einem technischen Sinne), weil diese verwalteten Ressourcen wahrscheinlich jetzt selbst für GC infrage kommen, oder es gibt eigentlich nichts, was standardmäßig verfügbar ist, und es ist ein Erweiterungspunkt.

Für unmanaged Ressourcen können Sie Dispose Muster empfiehlt die Implementierung eines Finalizers , der auf dem GC aufgerufen wird. Wenn Typen den Finalizer nicht implementieren und dispose nicht aufgerufen wird, ist es möglich (na ja, sehr wahrscheinlich), dass Ressourcen nicht behandelt werden. Finalizer sind die letzte Möglichkeit, die von der Laufzeit angeboten wird, um Ihre Sachen zu löschen - sie sind auch zeitlich begrenzt.

Beachten Sie, dass die GC- oder managed-Speicher-Reklamation nicht deterministisch ist, daher ist nicht delete von C ++. Ein entsorgter Gegenstand könnte weit entfernt davon sein, tatsächlich gesammelt zu werden. In der verwalteten Welt interessiert Sie jedoch nicht die deterministische Sammlung, sondern nur das Ressourcenmanagement, also die Entsorgung.

Das heißt, ich stelle immer sicher, dass ich Dispose anrufe oder eine using Anweisung verwende, wenn ein Typ wegwerfbar ist, unabhängig davon, ob er verwaltete oder nicht verwaltete Ressourcen verwendet - es ist die erwartete Konvention:

%Vor%

Aktualisierung:

Nach einem Gespräch mit Servy glaube ich, dass ich diesen Punkt als den Grund für meinen Ratschlag der Entsorung ausdrücken muss, wo es möglich ist. Bei MemoryStream handelt es sich eindeutig um einen Disposable-Typ, über den aber aktuell eigentlich nichts verfügt.

Dabei ist es jedoch wichtig, sich auf die Implementierung von MemoryStream zu verlassen. Würde sich dies ändern, um eine nicht verwaltete Ressource einzubeziehen, würde dies bedeuten, dass die Abhängigkeit von MemoryStream , die nicht über etwas verfügen muss, problematisch wird.

Wenn möglich (wie bei IDisposable ) bevorzuge ich den öffentlichen Auftrag . Wenn ich in diesem Fall gegen den Vertrag arbeite, wäre ich vor den zugrunde liegenden Implementierungsänderungen sicher.

    
Adam Houldsworth 12.07.2012 14:41
quelle
4

Obwohl Sie in C # imo selten manuell disponieren müssen, könnten Sie es wie folgt versuchen:

%Vor%

Dann wird es bei der letzten Auszeichnung des Benutzerteils automatisch entsorgt.

    
Gerald Versluis 12.07.2012 14:42
quelle
3

Sie könnten einfach tun:

%Vor%     
Druid 12.07.2012 14:41
quelle
1

Wenn Sie explizit disponieren möchten, verwenden Sie

%Vor%

Dies stellt sicher, dass Dispose () aufgerufen wird und sofort auftritt

    
James 12.07.2012 14:42
quelle
1

ShowDialog hat den Nebeneffekt, dass die GDI-Objekte am Leben erhalten bleiben. Um GDI-Lecks zu vermeiden, müssen wir den ShowDialog entsprechend entsorgen. Wo die Show-Methode keine Auswirkungen hat, wird GDI entsprechend freigegeben. Es wird empfohlen, den showDialog zu entsorgen und sich nicht auf den Garbage Collector zu verlassen.

    
Mendy 10.10.2016 10:13
quelle

Tags und Links