C # Form.Close vs Form.Dispose

88

Ich bin neu in C # und habe versucht, mir die früheren Beiträge anzusehen, aber keine gute Antwort gefunden.

Verwenden Sie in einer C # Windows Form-Anwendung mit einem einzelnen Formular Form.Close()besser oder Form.Dispose()?

MSDN sagt, dass alle Ressourcen innerhalb des Objekts geschlossen sind und das Formular beim Aufrufen eines Abschlusses entsorgt wird. Trotzdem bin ich online auf einige Beispiele gestoßen, die eher einer Dispose als einer Close folgen.

Hat einer einen Vorteil gegenüber dem anderen? In welchen Szenarien sollten wir eines dem anderen vorziehen?

topgun_ivard
quelle
Etwas andere Frage, gleiche Antwort, IMO: dh Schließen und Entsorgen sind normalerweise gleichwertig, außer dass Sie Schließen mehr als einmal aufrufen können.
ChrisW
2
@Chrisw: Sie können Dispose auch mehrmals aufrufen.
Henk Holterman
@ChrisW, Dispose sollte so konzipiert sein, dass es auch mehrmals ausgeführt wird. bluebytesoftware.com/blog/…
Steven Evers
Die Sache, die mich so nahe gebracht hat === entsorgen statt schließen == form.Visible = false; Ich hatte erwartet, dass das Schließen eine weichere Methode sein würde als das Entsorgen.
Pete Kirkham
4
@ Pete Kirkham: Wenn Sie möchten form.Visible = false;, können Sie anrufen form.Hide(). In der Tat form.Hide()einfach setzt this.Visible = false;.
Dirk Vollmar

Antworten:

168

Dieses Forum auf MSDN sagt es Ihnen.

Form.Close()sendet die richtigen Windows-Nachrichten, um das Win32-Fenster herunterzufahren. Wenn das Formular während dieses Vorgangs nicht modal angezeigt wurde, wird Dispose im Formular aufgerufen. Durch das Entsorgen des Formulars werden die nicht verwalteten Ressourcen freigegeben, an denen das Formular festhält.

Wenn Sie ein form1.Show()oder Application.Run(new Form1())ausführen, wird Dispose aufgerufen, wenn Close()es aufgerufen wird.

Wenn Sie form1.ShowDialog() das Formular jedoch modal anzeigen, wird das Formular nicht entsorgt, und Sie müssen sich form1.Dispose()selbst anrufen . Ich glaube, dies ist das einzige Mal, dass Sie sich Sorgen machen sollten, das Formular selbst zu entsorgen.

Kyra
quelle
Hat die 1. Version das Zitat enthalten? +1 zum Ausgleich.
Henk Holterman
@ Dan die erste Version saugte ... (Sorry @ Kyra)
jjnguy
13
Dies ist etwas anderes als die MSDN-Zustände unter msdn.microsoft.com/en-us/library/… : "Die einzige Bedingung, wenn ein Formular beim Schließen nicht entsorgt wird, ist, wenn es Teil einer Schnittstelle für mehrere Dokumente (MDI) ist. Anwendung, und das Formular ist nicht sichtbar. In diesem Fall müssen Sie Dispose manuell aufrufen, um alle Steuerelemente des Formulars für die Speicherbereinigung zu markieren. " Es sollte jedoch leicht zu überprüfen sein, ob modale Formen mit einer einfachen Stichprobe entsorgt werden oder nicht.
Dirk Vollmar
14

In der Regel würde ich immer empfehlen, die Dispose-Methode für jede Klasse, die sie anbietet, explizit aufzurufen, indem Sie die Methode entweder direkt aufrufen oder in einen "using" -Block einschließen.

In den meisten Fällen tun dies Klassen, die IDisposible implementieren, weil sie eine nicht verwaltete Ressource umschließen, die freigegeben werden muss. Während diese Klassen Finalizer haben sollten, die als Schutz dienen, hilft das Aufrufen von Dispose dabei, diesen Speicher früher und mit geringerem Overhead freizugeben.

Im Fall des Formularobjekts ist, wie im Link zu Kyra angegeben, die Close-Methode dokumentiert, um Dispose in Ihrem Namen aufzurufen, sodass Sie dies nicht explizit tun müssen. Für mich war es jedoch immer so, als würde ich mich auf ein Implementierungsdetail verlassen. Ich ziehe es vor, Close und Dispose immer für Klassen aufzurufen, die sie implementieren, um Änderungen / Fehlern bei der Implementierung vorzubeugen und um klar zu sein. Eine ordnungsgemäß implementierte Dispose-Methode sollte sicher mehrere Male aufgerufen werden können.

Jesse Squire
quelle
6

Wenn Sie nicht anrufen, wird Closewahrscheinlich das Senden einer Reihe von Win32-Nachrichten umgangen, von denen man denken würde, dass sie etwas wichtig sind, obwohl ich Ihnen nicht genau sagen kann, warum ...

Closehat den Vorteil, dass Ereignisse (die abgesagt werden können) so ausgelöst werden, dass ein Außenstehender (auf das Formular) achten FormClosingund FormClosedentsprechend reagieren kann.

Ich bin mir nicht sicher, ob FormClosingund / oder FormClosedob ich angehoben werde, wenn Sie das Formular einfach entsorgen, aber ich überlasse es Ihnen, damit zu experimentieren.

Roter Hund
quelle
2
Wenn Sie das Formular entsorgen, werden schließende und geschlossene Ereignisse nicht aufgerufen.
Matrix
4
Das Aufrufen der Dispose-Methode würde ein Flackern des Fensters verursachen, wenn es in Modal-Form über dem mdi-child-Fenster verwendet wird
dotNETbeginner
1

Verwenden usingist ein ziemlich guter Weg:

using (MyForm foo = new MyForm())
{
    if (foo.ShowDialog() == DialogResult.OK)
    {
        // your code
    }
}
Mustafa Burak Kalkan
quelle
0

Close () - Die verwaltete Ressource kann vorübergehend geschlossen und erneut geöffnet werden.

Dispose () - Entfernt dauerhaft verwaltete oder nicht verwaltete Ressourcen

Yuresh Karunanayake
quelle
3
Dies gilt nur, wenn das Formular mit angezeigt wurde ShowDialog(). Andernfalls Close()wird auch das Formular entsorgt.
Peter Duniho
-1

Wenn Sie form.close () in Ihrem Formular verwenden und das FormClosing-Ereignis Ihres Formulars festlegen und entweder form.close () in diesem Ereignis verwenden, geraten Sie in eine unbegrenzte Schleife, und Argumente außerhalb des Bereichs sind aufgetreten. Die Lösung besteht darin, das Formular zu ändern .close () mit form.dispose () im Falle von FormClosing. Ich hoffe dieser kleine Tipp hilft dir !!!

Hadi Erfanian
quelle
-1

Was ich gerade mit VS-Diagnosetools experimentiert habe, ist, dass ich dies nenne. Close () und dann das Ereignis formclosing ausgelöst. Wenn ich dann this.Dispose () am Ende des Formclosing-Ereignisses aufrufe, in dem ich viele andere Objekte darin entsorge, wird alles viel reibungsloser bereinigt.

Smoothumut
quelle