C # Form.Close vs Form.Dispose

88

Je suis nouveau sur C # et j'ai essayé de regarder les articles précédents mais je n'ai pas trouvé de bonne réponse.

Dans une application Windows Form C # avec un seul formulaire, est-ce que l'utilisation est Form.Close()meilleure ou Form.Dispose()?

MSDN indique que toutes les ressources de l'objet sont fermées et que le formulaire est supprimé lorsqu'une fermeture est appelée. Malgré cela, j'ai rencontré plusieurs exemples en ligne qui suivent une mise au rebut plutôt qu'une clôture.

L'un a-t-il un avantage sur l'autre? Dans quels scénarios devrions-nous préférer l'un à l'autre?

topgun_ivard
la source
Question légèrement différente, même réponse, IMO: c.-à-d. Close et Dispose sont généralement équivalents, sauf que vous pouvez appeler Close plus d'une fois.
ChrisW
2
@Chrisw: Vous pouvez également appeler Dispose plus d'une fois.
Henk Holterman
@ChrisW, Dispose doit également être conçu pour s'exécuter plus d'une fois. bluebytesoftware.com/blog/…
Steven Evers
La chose qui m'a fait fermer === disposer plutôt que fermer == form.Visible = false; Je m'attendais à ce que la fermeture soit une méthode plus douce que l'élimination.
Pete Kirkham
4
@Pete Kirkham: Si vous voulez, form.Visible = false;vous pouvez appeler form.Hide(). En fait, form.Hide()définit simplement this.Visible = false;.
Dirk Vollmar

Réponses:

171

Ce forum sur MSDN vous le dit.

Form.Close()envoie les messages Windows appropriés pour fermer la fenêtre win32. Au cours de ce processus, si le formulaire n'a pas été affiché de manière modale, Dispose est appelé sur le formulaire. La suppression du formulaire libère les ressources non gérées que le formulaire conserve.

Si vous faites un form1.Show()ou Application.Run(new Form1()), Dispose sera appelé quand il Close()est appelé.

Cependant, si vous form1.ShowDialog() affichez le formulaire de manière modale, le formulaire ne sera pas supprimé et vous devrez vous appeler form1.Dispose(). Je pense que c'est la seule fois où vous devriez vous soucier de vous débarrasser du formulaire.

Kyra
la source
La 1ère version incluait-elle le devis? +1 pour compenser.
Henk Holterman
@Dan la première version suce ... (Désolé @Kyra)
jjnguy
13
Ce n'est pas la même chose que les états MSDN à msdn.microsoft.com/en-us/library/… : "La seule condition lorsqu'un formulaire n'est pas supprimé à la fermeture est lorsqu'il fait partie d'une interface à plusieurs documents (MDI) application et le formulaire n'est pas visible. Dans ce cas, vous devrez appeler Dispose manuellement pour marquer tous les contrôles du formulaire pour le garbage collection. " Cependant, il devrait être facile de vérifier si les formulaires modaux sont supprimés ou non avec un simple échantillon.
Dirk Vollmar
14

En règle générale, je préconiserais toujours d'appeler explicitement la méthode Dispose pour toute classe qui la propose, soit en appelant directement la méthode, soit en l'enveloppant dans un bloc "using".

Le plus souvent, les classes qui implémentent IDisposible le font car elles encapsulent une ressource non gérée qui doit être libérée. Alors que ces classes doivent avoir des finaliseurs qui agissent comme une sauvegarde, l'appel de Dispose aidera à libérer cette mémoire plus tôt et avec une surcharge réduite.

Dans le cas de l'objet Form, comme le lien vers Kyra l'a noté, la méthode Close est documentée pour appeler Dispose en votre nom, vous n'avez donc pas besoin de le faire explicitement. Cependant, pour moi, cela a toujours eu l'impression de s'appuyer sur un détail d'implémentation. Je préfère toujours appeler Close et Dispose pour les classes qui les implémentent, pour se prémunir contre les changements / erreurs d'implémentation et dans un souci de clarté. Une méthode Dispose correctement implémentée doit pouvoir être invoquée en toute sécurité plusieurs fois.

Jesse Squire
la source
6

Ne pas appeler permet Closeprobablement de contourner l'envoi de nombreux messages Win32 que l'on pourrait penser être quelque peu importants bien que je ne puisse pas vous dire spécifiquement pourquoi ...

Closea l'avantage de déclencher des événements (qui peuvent être annulés) de telle sorte qu'un étranger (au formulaire) puisse surveiller FormClosinget FormClosedréagir en conséquence.

Je ne sais pas si FormClosinget / ou FormClosedsont soulevés si vous disposez simplement du formulaire, mais je vous laisse l'expérimentation.

Chien rouge
la source
2
Si vous supprimez le formulaire, les événements de fermeture et de fermeture ne sont pas appelés.
matrice du
4
l'appel de la méthode Dispose provoquerait un scintillement de la fenêtre lorsqu'elle était utilisée sur Modal-Form sur la fenêtre mdi-child
dotNETbeginner
1

L'utilisation usingest un très bon moyen:

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

Fermer () - la ressource gérée peut être temporairement fermée et peut être ouverte à nouveau.

Dispose () - supprime définitivement les ressources gérées ou non gérées

Yuresh Karunanayake
la source
3
Cela n'est vrai que si le formulaire a été affiché en utilisant ShowDialog(). Sinon, Close()supprimera également le formulaire.
Peter Duniho
-1

Si vous utilisez form.close () dans votre formulaire et définissez l'événement FormClosing de votre formulaire et que vous utilisez form.close () dans cet événement, vous tombez dans une boucle illimitée et un argument hors de portée s'est produit et la solution est de changer le formulaire .close () avec form.dispose () dans Event of FormClosing. J'espère que cette petite astuce vous aidera !!!

Hadi Erfanian
la source
-1

Ce que je viens d'expérimenter avec les outils de diagnostic VS, c'est que j'ai appelé this.Close () puis l'événement formclosing déclenché. Ensuite, lorsque j'appelle this.Dispose () à la fin de l'événement Formclosing où je dispose de nombreux autres objets, il nettoie tout beaucoup plus en douceur.

smoothumut
la source